/* tokens.css — omaralbawab.com
   The only source of colors, fonts, z-indexes, region boxes and breakpoints.
   Builders use these custom properties and nothing else (CONTRACT.md "Colors and type").
   The integrator may tune the SEAM and REGION groups; nobody else edits this file.
   Phone values live in the single media query at the bottom. */

:root {
  /* ---------- breakpoints ---------- */
  --bp-phone: 640px;            /* <= this width is "phone": two bands + card */
  --bp-short: 700px;            /* <= this height: card tightens its padding */

  /* ---------- NIGHT (left half) ---------- */
  --night: #07070C;             /* the dark. Never #000. */
  --night-deep: #030305;        /* only for the extreme top-left corner */
  --night-haze: #171A28;        /* mist / nebula tint, used at low alpha */
  --dusk: #4A4668;              /* the twilight tint that colours the seam */
  --star: #ECEAE5;              /* stars, at alpha .2-.9 */
  --star-warm: #F3E6C8;         /* the few brighter stars */
  --moonlight: #C3CCEA;         /* glow around the moon, alpha <= .16 */
  --bit: #ECEAE5;               /* code glyphs, alpha <= .62 */
  --bit-dim: #8C8E9C;           /* code glyphs that are "further away" */

  /* ---------- MIND (top-right, the toned white) ---------- */
  --mind: #ECEAE4;              /* base. The old #F7F6F2 was the "domineering" white. */
  --mind-bright: #F5F3EE;       /* ONE soft luminous spot: the opening in the head */
  --mind-shade: #DFDCD4;        /* paper falling off toward the top-right corner */
  --mind-warm: #F0E4D0;         /* midpoint on the way to parchment */
  --mind-glow: #F2DDB4;         /* the warm light inside the mind, alpha <= .9 */
  --graphite: #3B3936;          /* mind line art. Never pure black. */
  --graphite-soft: #6E6B66;     /* secondary / distant lines */

  /* ---------- PARCHMENT (bottom-right) — matched to reference/parchment-swatch.png
     (sampled: p5 #EEDCBF, p50 #F2E0C5, p95 #F8E6CC — cream, not yellow, not brown) */
  --parch: #F2E0C5;
  --parch-light: #F7E7CF;
  --parch-deep: #E8D2B1;        /* mottle tone, used at alpha <= .4 */
  --parch-edge: #E5CDAA;        /* only the extreme bottom-right corner */
  --ink: #1E1C19;               /* book line art, writing. Never pure black. */
  --sepia: #5B4630;             /* warm line art, hatching */
  --sepia-soft: #8A7355;        /* faded writing, page edges */
  --cedar: #B08A62;             /* pencil wood. No primary-coloured pencils. */

  /* ---------- CARD ---------- */
  --card-bg: #0E0E12;
  --card-bg-glass: rgba(14, 14, 18, .32);   /* was .46; lowered so the art shows through (refiner) */
  --card-blur: 18px;
  --card-border: rgba(255, 255, 255, .09);
  --card-text: #ECEAE5;
  --card-muted: #8F8C85;
  --card-link-bg: rgba(255, 255, 255, .045);
  --card-link-bg-hover: rgba(255, 255, 255, .085);
  --card-link-border: rgba(255, 255, 255, .08);
  --card-link-border-hover: rgba(255, 255, 255, .16);
  --card-focus: #D9C7A0;        /* focus ring; 2px solid, offset 2px */
  --card-shadow: 0 30px 80px rgba(0, 0, 0, .45), 0 0 0 1px rgba(0, 0, 0, .4);
  --card-radius: 22px;
  --card-w: min(360px, calc(100vw - 40px));
  --card-pad: 1.9rem 1.4rem 1.4rem;
  --card-max-h: 440px;          /* budget, not a clip: the card must fit this */
  --link-h: 48px;
  --link-gap: .55rem;
  --link-radius: 12px;
  --link-pad-x: 1rem;

  /* ---------- TYPE ---------- */
  --font-serif: 'Instrument Serif', 'Iowan Old Style', 'Times New Roman', serif;
  --font-sans: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --fs-name: 2.3rem;            /* h1, Instrument Serif 400, letter-spacing -.02em, line-height 1 */
  --fs-tagline: .88rem;         /* DM Sans 400, line-height 1.45, color --card-muted */
  --fs-link: .95rem;            /* DM Sans 500 */
  --fs-link-arrow: .8rem;       /* the ↗, DM Sans 400, color --card-muted */
  --fs-bit: 13px;               /* code glyphs (monospace) */
  --lh-bit: 18px;               /* code row pitch */
  --bit-col: 15px;              /* code column pitch */

  /* ---------- Z ---------- */
  --z-stage: 0;                 /* stage backgrounds */
  --z-corner: 10;               /* all four corners share this; masks do the blending */
  --z-grain: 20;                /* film grain, above art, below card */
  --z-card: 30;
  --z-harness: 100;             /* preview/frame chrome only; never in index.html */

  /* ---------- MOTION ---------- */
  --t-breathe: 12s;             /* glows: opacity +-.04, scale <= 1.02 */
  --t-drift: 48s;               /* mists, clouds: translate <= 1.5% of the piece box */
  --t-twinkle: 7s;              /* a single star's cycle (phase-offset per star) */
  --t-reveal: 32s;              /* slow reveals (handwriting), with an 8s rest */
  --bit-speed: 8px;             /* code fall speed per second (6-10 px/s) */
  --ease-calm: cubic-bezier(.4, 0, .2, 1);
  --t-hover: 220ms;             /* the only "fast" transition, card links only */

  /* ---------- SEAM (the stage draws it; corners fade toward it) ----------
     The night ends on a line tilted so the sky leans over the card: it crosses the top
     edge at ~53vw and the bottom edge at ~47vw on desktop. Percentages are along the
     gradient line of linear-gradient(var(--seam-angle), ...). */
  --seam-angle: 96deg;
  --seam-start: 38%;            /* night fully opaque until here */
  --seam-mid: 50%;              /* the seam itself */
  --seam-end: 62%;              /* night fully gone */
  --warm-start: 30vh;           /* mind white still pure above this */
  --warm-end: 62vh;             /* parchment pure below this */

  /* ---------- MOON (client: "smaller and higher in the left corner") ---------- */
  --moon-size: min(15vw, 19vh);
  --moon-top: 6vh;
  --moon-left: 6vw;

  /* ---------- GRAIN ---------- */
  --grain-opacity: .055;
  --grain-tile: 240px;

  /* ---------- REGIONS (desktop) ---------- */
  --region-w: 60vw;             /* every corner box is 60vw x 62vh, anchored to its corner */
  --region-h: 62vh;             /* so corners overlap 40-60vw and 38-62vh on purpose */
  --fade-seam: 58%;             /* corner fully opaque until here (of its own width) toward the seam */
  --fade-neighbour: 60%;        /* ... and until here (of its own height) toward its neighbour */
}

/* ---------- corner boxes ----------
   The corner root positions itself; it can be injected anywhere in <body>.
   The mask is applied here so all four blend the same way. Do NOT override
   position, inset, width, height, mask-* or z-index on the root. */
.corner {
  position: fixed;
  z-index: var(--z-corner);
  width: var(--region-w);
  height: var(--region-h);
  overflow: hidden;
  pointer-events: none;
  contain: layout paint;
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
}
.corner--cosmos {
  top: 0; left: 0;
  -webkit-mask-image: linear-gradient(to right,  #000 var(--fade-seam), transparent 100%),
                      linear-gradient(to bottom, #000 var(--fade-neighbour), transparent 100%);
          mask-image: linear-gradient(to right,  #000 var(--fade-seam), transparent 100%),
                      linear-gradient(to bottom, #000 var(--fade-neighbour), transparent 100%);
}
.corner--mind {
  top: 0; right: 0;
  -webkit-mask-image: linear-gradient(to left,   #000 var(--fade-seam), transparent 100%),
                      linear-gradient(to bottom, #000 var(--fade-neighbour), transparent 100%);
          mask-image: linear-gradient(to left,   #000 var(--fade-seam), transparent 100%),
                      linear-gradient(to bottom, #000 var(--fade-neighbour), transparent 100%);
}
.corner--code {
  bottom: 0; left: 0;
  -webkit-mask-image: linear-gradient(to right,  #000 var(--fade-seam), transparent 100%),
                      linear-gradient(to top,    #000 var(--fade-neighbour), transparent 100%);
          mask-image: linear-gradient(to right,  #000 var(--fade-seam), transparent 100%),
                      linear-gradient(to top,    #000 var(--fade-neighbour), transparent 100%);
}
.corner--books {
  bottom: 0; right: 0;
  -webkit-mask-image: linear-gradient(to left,   #000 var(--fade-seam), transparent 100%),
                      linear-gradient(to top,    #000 var(--fade-neighbour), transparent 100%);
          mask-image: linear-gradient(to left,   #000 var(--fade-seam), transparent 100%),
                      linear-gradient(to top,    #000 var(--fade-neighbour), transparent 100%);
}

/* ---------- SEAM RAMPS (integrator, 2026-10-28; logged in INTEGRATION.md) ----------
   stage.html declares an 11-stop smoothstep night mask and then overrides it with a 5-stop ramp; that ramp's slope kink at --seam-start is the faint
   vertical step at ~38% along the seam line (x ~ 150px on a 390 phone, ~37vw on desktop).
   The dusk band's 5-stop mask also kinks at its peak. Both are restored here as C1-smooth
   ramps (smoothstep for the night, cos^2 bell for the dusk) over the same token positions,
   so no Mach band can form. Same extents and the same .5 at --seam-mid as before. */
.stage .stage__night {
  -webkit-mask-image: linear-gradient(var(--seam-angle),
    #000 calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.0000),
    rgba(0,0,0,0.980) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.0833),
    rgba(0,0,0,0.926) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.1667),
    rgba(0,0,0,0.844) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.2500),
    rgba(0,0,0,0.741) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.3333),
    rgba(0,0,0,0.624) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.4167),
    rgba(0,0,0,0.500) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.5000),
    rgba(0,0,0,0.376) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.5833),
    rgba(0,0,0,0.259) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.6667),
    rgba(0,0,0,0.156) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.7500),
    rgba(0,0,0,0.074) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.8333),
    rgba(0,0,0,0.020) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.9167),
    transparent calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 1.0000));
          mask-image: linear-gradient(var(--seam-angle),
    #000 calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.0000),
    rgba(0,0,0,0.980) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.0833),
    rgba(0,0,0,0.926) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.1667),
    rgba(0,0,0,0.844) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.2500),
    rgba(0,0,0,0.741) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.3333),
    rgba(0,0,0,0.624) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.4167),
    rgba(0,0,0,0.500) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.5000),
    rgba(0,0,0,0.376) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.5833),
    rgba(0,0,0,0.259) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.6667),
    rgba(0,0,0,0.156) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.7500),
    rgba(0,0,0,0.074) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.8333),
    rgba(0,0,0,0.020) calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 0.9167),
    transparent calc(var(--seam-start) + (var(--seam-end) - var(--seam-start)) * 1.0000));
}
.stage .stage__dusk {
  /* peak raised from stage.html's .34 (final refiner): at .34 the seam read neutral grey above
     and below the desktop card, not the twilight violet DIRECTION §2 asks for */
  opacity: .5;
  -webkit-mask-image: linear-gradient(var(--seam-angle),
    transparent calc(var(--seam-mid) - 18.000%),
    rgba(0,0,0,0.038) calc(var(--seam-mid) - 15.750%),
    rgba(0,0,0,0.146) calc(var(--seam-mid) - 13.500%),
    rgba(0,0,0,0.309) calc(var(--seam-mid) - 11.250%),
    rgba(0,0,0,0.500) calc(var(--seam-mid) - 9.000%),
    rgba(0,0,0,0.691) calc(var(--seam-mid) - 6.750%),
    rgba(0,0,0,0.854) calc(var(--seam-mid) - 4.500%),
    rgba(0,0,0,0.962) calc(var(--seam-mid) - 2.250%),
    #000 calc(var(--seam-mid) + 0%),
    rgba(0,0,0,0.962) calc(var(--seam-mid) + 2.250%),
    rgba(0,0,0,0.854) calc(var(--seam-mid) + 4.500%),
    rgba(0,0,0,0.691) calc(var(--seam-mid) + 6.750%),
    rgba(0,0,0,0.500) calc(var(--seam-mid) + 9.000%),
    rgba(0,0,0,0.309) calc(var(--seam-mid) + 11.250%),
    rgba(0,0,0,0.146) calc(var(--seam-mid) + 13.500%),
    rgba(0,0,0,0.038) calc(var(--seam-mid) + 15.750%),
    transparent calc(var(--seam-mid) + 18.000%));
          mask-image: linear-gradient(var(--seam-angle),
    transparent calc(var(--seam-mid) - 18.000%),
    rgba(0,0,0,0.038) calc(var(--seam-mid) - 15.750%),
    rgba(0,0,0,0.146) calc(var(--seam-mid) - 13.500%),
    rgba(0,0,0,0.309) calc(var(--seam-mid) - 11.250%),
    rgba(0,0,0,0.500) calc(var(--seam-mid) - 9.000%),
    rgba(0,0,0,0.691) calc(var(--seam-mid) - 6.750%),
    rgba(0,0,0,0.854) calc(var(--seam-mid) - 4.500%),
    rgba(0,0,0,0.962) calc(var(--seam-mid) - 2.250%),
    #000 calc(var(--seam-mid) + 0%),
    rgba(0,0,0,0.962) calc(var(--seam-mid) + 2.250%),
    rgba(0,0,0,0.854) calc(var(--seam-mid) + 4.500%),
    rgba(0,0,0,0.691) calc(var(--seam-mid) + 6.750%),
    rgba(0,0,0,0.500) calc(var(--seam-mid) + 9.000%),
    rgba(0,0,0,0.309) calc(var(--seam-mid) + 11.250%),
    rgba(0,0,0,0.146) calc(var(--seam-mid) + 13.500%),
    rgba(0,0,0,0.038) calc(var(--seam-mid) + 15.750%),
    transparent calc(var(--seam-mid) + 18.000%));
}

/* ---------- the card slot ----------
   Position and width only. Everything inside is the card team's. */
.card {
  position: fixed;
  z-index: var(--z-card);
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: var(--card-w);
  box-sizing: border-box;
}

/* ---------- PHONE (<= 640px): two bands, card over the middle ----------
   Visible band above the card: 0-29vh. Card: ~29-71vh. Band below: 71-100vh.
   Corner boxes reach to 50vh so art continues behind the card (matters for glass). */
@media (max-width: 640px) {
  :root {
    --region-w: 62vw;
    --region-h: 50vh;
    --fade-seam: 55%;
    --fade-neighbour: 60%;
    --seam-angle: 92deg;
    --warm-start: 34vh;
    --warm-end: 64vh;
    --moon-size: 22vw;
    --moon-top: 3vh;
    --moon-left: 7vw;
    --card-w: min(320px, calc(100vw - 56px));
    --card-pad: 1.5rem 1.1rem 1.1rem;
    --card-radius: 20px;
    --card-max-h: 42vh;
    --link-h: 46px;
    --link-gap: .5rem;
    --fs-name: 2rem;
    --fs-bit: 11px;
    --lh-bit: 15px;
    --bit-col: 13px;
    --grain-opacity: .05;
  }
  /* The code field alone reaches higher on phones (client, 2026-10-28): digits should show
     just under the card, not only at the foot of the screen. */
  .corner--code { --region-h: 62vh; }
}
@media (max-height: 700px) {
  :root {
    --card-pad: 1.25rem 1.1rem 1rem;
    --link-h: 44px;
    --link-gap: .45rem;
    --fs-name: 1.9rem;
  }
}
/* Short phones (final refiner, 2026-10-28): Instagram's in-app browser is 390 x ~664-740, where
   most visitors land. With card.css's matching tier this takes the card from ~330-340px to
   ~304px. Rows stay full-width 40px tap targets. */
@media (max-width: 640px) and (max-height: 760px) {
  :root {
    --link-h: 40px;
    --link-gap: .35rem;
    --card-pad: 1.1rem 1rem .85rem;
    --fs-name: 1.75rem;
  }
}
/* Phones measure against the SMALL viewport. The page never scrolls, so mobile toolbars never
   collapse, and 100vh (the large viewport) is 60-110px taller than what the visitor sees.
   Custom properties can't fall back by declaring twice (the svh copy would always win and go
   invalid where unsupported), so svh sits behind @supports; older browsers keep the vh above. */
@supports (height: 1svh) {
  @media (max-width: 640px) {
    :root {
      --region-h: 50svh;
      --warm-start: 34svh;
      --warm-end: 64svh;
      --moon-top: 3svh;
      --card-max-h: 42svh;
    }
    .corner--code { --region-h: 62svh; }
  }
}
