/* 0. The entry card, HPR-C1: a telecoms calling card from a future that happened in about 1999. Somewhat
   translucent resin with a faint aqua tint, 1.8 mm thick, over a dense board (an orange flex under the main
   chip, a coil of copper round the edge), the wordmark in embossed silver foil worn off its high points, Work
   and Methods in raised ink on a sandblasted panel, a glossy holographic seal with one corner lifted, and
   Enter as a recess in the resin: a chrome contact ring at the face, the word laser-etched into the floor,
   an LED under it. The card is drawn and lit by assets/hybrid/entry/ (WebGL, or a Canvas 2D still); this
   sheet sets its size and its perspective, the DOM layer that carries the text, the key and the back, the
   turn button, and the plain card for when the module cannot draw. Type, timing and ground come from the
   shell's tokens. */

.gate {
  display: none; position: fixed; inset: 0; z-index: 150; overflow: hidden; touch-action: pinch-zoom;
  /* the key light's pool, up and to the left, on the silver ground */
  background:
    radial-gradient(85% 75% at 30% 20%, rgba(255, 255, 255, 0.74), rgba(255, 255, 255, 0) 64%),
    radial-gradient(120% 90% at 50% 120%, rgba(150, 160, 170, 0.16), rgba(150, 160, 170, 0) 60%),
    linear-gradient(180deg, #f2f4f6, var(--silver) 55%, #e4e7ea);
  transition: opacity var(--t-move) var(--ease) var(--stagger), visibility 0s var(--ease) calc(var(--t-move) + var(--stagger));
}
.gate::before {
  content: ""; position: absolute; inset: 0; opacity: 0.3; mix-blend-mode: soft-light; pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='900' height='900'><filter id='b'><feTurbulence type='fractalNoise' baseFrequency='0.0016 0.82' numOctaves='2' seed='7'/><feColorMatrix values='0 0 0 0 0.5  0 0 0 0 0.5  0 0 0 0 0.5  0.9 0 0 0 0'/></filter><rect width='100%' height='100%' filter='url(%23b)'/></svg>");
}
html.gated .gate { display: grid; place-items: center; }
html.gated body { overflow: hidden; }
html.gate-leaving .gate { opacity: 0; visibility: hidden; }

/* The card's box: ID-1 proportions, wide on every screen (a phone held upright fits it to its width, between the
   gutters), as large as the screen allows. The renderer reads this box (in whole pixels) and sets the same
   perspective on it that the lit card is cast in. */
.gate-stage {
  --card-w: min(660px, calc(100vw - 2 * var(--gutter)), calc((100vh - 96px) * 1.5858));
  --card-h: calc(var(--card-w) * 0.63061);
  --mm: calc(var(--card-w) / 85.6);
  position: relative; width: var(--card-w); height: var(--card-h);
  perspective: calc(var(--card-w) * 2.8);
  opacity: 0;
}
@supports (height: 100svh) { .gate-stage { --card-w: min(660px, calc(100vw - 2 * var(--gutter)), calc((100svh - 96px) * 1.5858)); } }
@supports (width: round(down, 10.5px, 1px)) { .gate-stage { width: round(down, var(--card-w), 1px); height: round(down, var(--card-h), 1px); } }
/* in over --t-scene once the card is drawn; out over --t-move (the inline script removes the gate at 760 ms) */
.gate-stage.is-ready, html.card-plain .gate-stage { opacity: 1; animation: card-in var(--t-scene) var(--ease) backwards; }
@keyframes card-in { from { opacity: 0; translate: 0 var(--s3); } to { opacity: 1; translate: 0 0; } }
html.gate-leaving .gate-stage { opacity: 0; translate: 0 calc(-1 * var(--s2)); transition: translate var(--t-move) var(--ease), opacity var(--t-move) var(--ease); }

/* the drawn card: the still first, the lit card over it once WebGL has drawn */
.card-still, .card-gl { position: absolute; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none; }
.card-gl { opacity: 0; transition: opacity var(--t-ui) var(--ease); }
.is-lit .card-gl { opacity: 1; }
.is-lit .card-still { opacity: 0; transition: opacity var(--t-ui) var(--ease) var(--stagger); }

/* the DOM layer, turned with the lit card about the slab's middle: the face toward the eye carries its text
   (read, not seen: the card prints it) and, at the front, the key; the other face turns away */
.card {
  position: absolute; inset: 0; pointer-events: none;   /* only the key takes the pointer: the tilted plane never steals a click */
  transform: rotateX(var(--card-rx, 0deg)) rotateY(calc(var(--card-ry, 0deg) + var(--card-flip, 0deg)));
  transform-style: preserve-3d;
}
.card-face { position: absolute; inset: 0; transform-style: preserve-3d; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.card-front { transform: translateZ(var(--card-half, calc(var(--mm) * 0.9))); }
.card-back { transform: rotateY(180deg) translateZ(var(--card-half, calc(var(--mm) * 0.9))); }
.card-back[hidden] { display: block; visibility: hidden; }
.card-print, .card-back > * { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; padding: 0; }
.card-print h2, .card-print dl, .card-print dd, .card-print p { margin: 0; }
html.card-flipped .card-front { pointer-events: none; }
html.card-flipped .card-enter { pointer-events: none; }

/* ------------------------------------------------------------------ Enter: a recess in the resin
   The button is the opening itself: the drawn card has the chrome contact ring at the face, the floor 0.6 mm
   down with the word etched into it, and the LED under the floor that lights on hover and focus and brighter
   on a press (the floor sinks a further 0.3 mm). The button draws nothing of its own but its focus ring. */
.card-enter {
  position: absolute; left: 69.39%; top: 77.07%; width: 23.6%; height: 12.6%;   /* layers.js key, in mm: 59.4, 41.6, 20.2 × 6.8 */
  margin: 0; padding: 0; border: 0; border-radius: 999px; background: none; color: inherit; font: inherit;
  cursor: pointer; -webkit-tap-highlight-color: transparent; pointer-events: auto;
}
.key-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* without WebGL the still has the recess drawn in: the key answers the pointer with the LED's light alone */
.is-flat .card-enter { transition: box-shadow var(--t-fast) var(--ease); }
@media (hover: hover) { .is-flat .card-enter:hover { box-shadow: inset 0 0 calc(var(--mm) * 3) rgba(40, 210, 190, 0.5), 0 0 calc(var(--mm) * 2.4) rgba(40, 210, 190, 0.32); } }
.is-flat .card-enter:active { box-shadow: inset 0 0 calc(var(--mm) * 3.4) rgba(40, 210, 190, 0.7), inset 0 2px 4px rgba(0, 30, 28, 0.4); }
/* Enter is focused from the first paint: its ring shows only once a key has been pressed */
.card-enter:focus-visible { outline: none; }
html.kbd .card-enter:focus-visible { outline: var(--ring); outline-offset: calc(var(--mm) * 0.9); }

/* the turn mark: TURN OVER and its pictogram, engraved at the card's lower left. layers.js reads this box and draws
   the mark in it. A click or a tap turns the card (the gate's script); the pointer over it lifts the card's left
   edge a little (card.js). It is for the pointer only and takes no focus: the keyboard has F and the turn button
   below. Its hit area reaches a little past the engraving (and further for a finger: see below). */
.card-turn {
  position: absolute; left: 10.05%; top: 79.66%; width: 15.42%; height: 8.15%;   /* layers.js turn, in mm: 8.6, 43.0, 13.2 × 4.4 */
  cursor: pointer; pointer-events: auto; -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.card-turn::after { content: ""; position: absolute; inset: calc(var(--mm) * -0.7); }
html.card-flipped .card-turn, html.card-plain .card-turn { pointer-events: none; }
html.card-plain .card-turn { display: none; }

/* the turn button: for the keyboard, it appears under the card when it has focus (F does the same) */
.card-flip { position: absolute; left: 50%; bottom: clamp(16px, 6vh, 64px); translate: -50% 0; white-space: nowrap; }
.card-flip:not(:focus-visible) { width: 1px; height: 1px; padding: 0; overflow: hidden; clip-path: inset(50%); border: 0; box-shadow: none; }

@media (prefers-reduced-motion: reduce) {
  .gate-stage.is-ready, html.card-plain .gate-stage { animation: none; }
  .gate, html.gate-leaving .gate-stage, .card-gl, .is-lit .card-still, .is-flat .card-enter { transition: none; }
}

/* forced colours: the drawn card keeps its own colours; the key gets a system outline so it still reads as a button */
@media (forced-colors: active) {
  .card-enter { border: 2px solid ButtonText; }
}

/* a finger: on a small card the key and the turn mark take a press a little beyond what is drawn (at 390 px wide the
   key is about 83 × 28 px drawn, 95 × 40 to the touch; the turn mark 54 × 18, 66 × 34). The key's own press and
   release (the gate's script) allow a further 12 px. */
@media (pointer: coarse) {
  .card-enter::after { content: ""; position: absolute; inset: -6px; border-radius: inherit; }
  .card-turn::after { inset: -8px -6px; }
}

/* ------------------------------------------------------------------ the plain card
   Only if the card's module cannot load or draw (html.card-plain, set by the gate's script): a pale card
   with its text set in the page's own type, a recessed key, and its back when it is turned over. */
html.card-plain .card { transform: none; }
html.card-plain .card-face { backface-visibility: visible; transform: none; }
html.card-plain .card-front, html.card-plain .card-back {
  border-radius: calc(var(--mm) * 3.18);
  background: linear-gradient(140deg, rgba(255, 255, 255, 0.86), rgba(226, 238, 240, 0.66));
  box-shadow: inset 0 1px 0 #fff, 0 0 0 1px rgba(10, 11, 12, 0.12), 0 50px 80px -40px rgba(12, 22, 32, 0.4);
}
html.card-plain .card-print {
  width: auto; height: auto; overflow: visible; clip-path: none; white-space: normal;
  inset: 8% 8% auto 8%; display: grid; gap: var(--s3); color: var(--ink);
}
html.card-plain .card-print h2 { font-family: var(--display); font-weight: 400; font-size: calc(var(--mm) * 7.2); line-height: 0.9; letter-spacing: var(--ls-mark); }
html.card-plain .card-print dl { display: grid; gap: var(--s2); max-width: 46ch; }
html.card-plain .card-print dt { font-family: var(--text); font-style: italic; font-size: var(--fs-meta); color: var(--quiet); }
html.card-plain .card-print dd { font-family: var(--text); font-size: var(--fs-ui); line-height: var(--lh-line); color: var(--graphite); }
html.card-plain .card-part { display: none; }
html.card-plain .card-enter {
  background: linear-gradient(180deg, rgba(8, 40, 40, 0.16), rgba(255, 255, 255, 0.3));
  box-shadow: inset 0 2px 4px rgba(0, 30, 30, 0.3), 0 0 0 2px #dfe3e7, 0 0 0 3px rgba(40, 46, 52, 0.4);
  font-family: var(--text); font-size: var(--fs-ui); color: var(--graphite);
}
html.card-plain .key-label { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }
html.card-plain .card-back { display: none; }
html.card-plain.card-flipped .card-front { display: none; }
html.card-plain.card-flipped .card-back { display: block; visibility: visible; padding: 7% 8%; overflow: auto; }
html.card-plain.card-flipped .card-back > * {
  position: static; width: auto; height: auto; overflow: visible; clip-path: none; white-space: normal;
  font-family: var(--text); font-size: 14px; line-height: 1.35; color: var(--graphite); margin: 0 0 var(--s1);
}
html.card-plain.card-flipped .card-back .cb-lines { padding: 0; list-style: none; }
/* on a phone the plain card is the wide card too, so its type is set by the card's millimetre to fit above the key */
@media (max-width: 600px) {
  html.card-plain .card-print { inset: 6% 6% auto 6%; gap: calc(var(--mm) * 1.4); }
  html.card-plain .card-print h2 { font-size: calc(var(--mm) * 6); }
  html.card-plain .card-print dl { gap: calc(var(--mm) * 1.1); }
  html.card-plain .card-print dt { font-size: calc(var(--mm) * 2.5); }
  html.card-plain .card-print dd { font-size: calc(var(--mm) * 2.75); line-height: 1.3; }
  html.card-plain .card-enter { font-size: calc(var(--mm) * 3.2); }
  html.card-plain.card-flipped .card-back { padding: 5% 6%; columns: 2; column-gap: calc(var(--mm) * 3.2); }
  html.card-plain.card-flipped .card-back > * { font-size: calc(var(--mm) * 2.4); line-height: 1.3; margin-bottom: calc(var(--mm) * 0.8); break-inside: avoid; }
}
