
/* Layout: one TV screen. Pages are channels stacked in place; a scroll, swipe or key changes the channel, one at a time.
   Work has an index of case studies beside the open one. */
:root {
  --screen: #131412;     /* soft black, a tube that is switched on */
  --phosphor: #efeadf;   /* warm white phosphor */
  --head: #efeadf;       /* headline colour */
  --dim: #8f8c84;
  --line: rgba(239, 234, 223, 0.12);
  --glow: 239, 234, 223; /* rgb of the phosphor glow */
  --live: #ff5a4e;       /* the red LIVE light */
  --live-rgb: 255, 90, 78;
  --label: #e9e4d6;      /* paper tape labels */
  --fringe: 0 0 22px rgba(239, 234, 223, 0.18);
  --title: "Archivo", "Arial Black", system-ui, sans-serif;
  --osd: "Lucida Console", "Courier New", monospace;
  --body: "IBM Plex Sans", system-ui, sans-serif; /* running text: quiet, from the same family as the mono labels */
  --mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace; /* small labels: crisp at any size */
  --gl: max(22px, env(safe-area-inset-left, 0px), 4.5vw);
  --gr: max(22px, env(safe-area-inset-right, 0px), 4.5vw);
  --ease: cubic-bezier(.22, 1, .36, 1);
  color-scheme: dark;
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { height: 100%; overflow: hidden; overscroll-behavior: none; background: var(--screen); transition: background-color .5s ease; }
body { margin: 0; color: var(--phosphor); font-family: var(--title); -webkit-font-smoothing: antialiased; }
/* the page also runs inside WordPress, where the theme's own styles load first: neutralise the ones that would leak in */
button { background: none; border: 0; border-radius: 0; box-shadow: none; color: inherit; font: inherit; letter-spacing: inherit; text-transform: none; padding: 0; margin: 0; }
/* hover and focus only undo a theme's colours; they leave padding and borders to the design's own rules */
button:where(:hover, :focus, :active) { background-color: transparent; box-shadow: none; color: inherit; }
/* :where keeps these at plain-link strength, so a visited or focused link never overrides a component's own colour */
h1, h2, p, ul, ol, dl, figure { margin: 0; }
svg { max-width: none; }
html, html body { background: var(--screen) !important; }
/* logged in to WordPress, its admin bar sits on top: move the fixed layer down out of its way */
body.admin-bar .brand { top: calc(52px + env(safe-area-inset-top, 0px)); }
body.admin-bar .osd, body.admin-bar .stage, body.admin-bar .guide { top: 32px; }
@media (max-width: 782px) { body.admin-bar .brand { top: 66px; } body.admin-bar .osd, body.admin-bar .stage, body.admin-bar .guide { top: 46px; } }
/* with a mouse, the drawn ring is the only pointer: no hand over buttons, no text caret over form fields */
@media (pointer: fine) { *, *::before, *::after { cursor: none !important; } }
::selection { background: var(--phosphor); color: var(--screen); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- on-screen display ---------- */
.osd {
  position: fixed; z-index: 40; left: 0; right: 0; top: 0;
  display: flex; justify-content: flex-end; align-items: flex-start; gap: 16px;
  padding: calc(24px + env(safe-area-inset-top, 0px)) var(--gr) 0 var(--gl);
  font-family: var(--osd); text-transform: uppercase; pointer-events: none;
  text-shadow: 0 0 8px rgba(var(--glow), 0.45);
}
.osd > * { pointer-events: auto; }
/* the mark: BELAL set sideways down the left edge, DIGITAL small beneath it */
/* the logo: a four-point sparkle. In the mark it is cut into the A of BELAL (Archivo's own A, traced, with the crossbar
   and its hole replaced by the sparkle; tools/spark.py draws it). Elsewhere it stands on its own */
:root { --spark-a: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1088 933'%3E%3Cpath fill-rule='evenodd' d='M210,15 L897.5,352 L897.5,580 L210,921 L210,697 L360,468 L210,224Z M782.6,468.2 C698.4,468.2 610.7,546.6 610.7,635 C610.7,543.3 519.2,468.2 447.4,468.2 C509.4,468.2 610.7,400.5 610.7,299 C610.7,383.6 686.3,468.2 782.6,468.2Z'/%3E%3C/svg%3E");
  --spark-a-red: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1088 933'%3E%3Cpath fill='%23efeadf' fill-rule='evenodd' d='M210,15 L897.5,352 L897.5,580 L210,921 L210,697 L360,468 L210,224Z M782.6,468.2 C698.4,468.2 610.7,546.6 610.7,635 C610.7,543.3 519.2,468.2 447.4,468.2 C509.4,468.2 610.7,400.5 610.7,299 C610.7,383.6 686.3,468.2 782.6,468.2Z'/%3E%3Cpath fill='%23ff5a4e' d='M782.6,468.2 C698.4,468.2 610.7,546.6 610.7,635 C610.7,543.3 519.2,468.2 447.4,468.2 C509.4,468.2 610.7,400.5 610.7,299 C610.7,383.6 686.3,468.2 782.6,468.2Z'/%3E%3C/svg%3E"); }
:root { --rail: clamp(min(78px, 13vh), 11.5vh, 124px); --edge: max(14px, env(safe-area-inset-left, 0px), 1.8vw); --mark: var(--rail); }
body { --edge-ink: calc(var(--edge) + var(--mark) * .039); } /* the menu keeps the gap BELAL has on Home, on every page */ /* where BELAL's letters actually start: the box has a little air before the ink */
.brand {
  position: fixed; z-index: 41; left: var(--edge); top: calc(20px + env(safe-area-inset-top, 0px));
  writing-mode: vertical-rl; display: flex; align-items: flex-end; gap: 0; color: var(--phosphor); text-decoration: none; /* flex-end is the left edge here, so the mark grows and shrinks from where it stands */
}
.brand b { font-family: var(--title); font-weight: 800; font-stretch: 125%; font-size: var(--rail); line-height: .74; letter-spacing: -0.035em; text-transform: uppercase; }
/* DIGITAL reads across in the narrowest cut of Archivo, so it can be as tall as possible while spanning exactly the width of the L above it */
.brand > span { writing-mode: horizontal-tb; font: 700 calc(var(--rail) * .13)/.9 var(--title); font-stretch: 62%; letter-spacing: .06em; text-transform: uppercase; color: var(--dim); white-space: nowrap; text-align: justify; text-align-last: justify; transition: color .4s, opacity .25s ease; }
/* away from home the mark folds to half size; DIGITAL turns on its side and runs up beside BELAL, still readable */
.brand b { -webkit-text-fill-color: var(--phosphor); transition: -webkit-text-fill-color .8s ease, opacity .5s ease; transform-origin: 0 0; }
/* while the mark folds or unfolds it is drawn at full size and scaled (see the mark in the script), and the DIGITAL
   on its side waits until BELAL has settled */
body.mark-big .brand b { font-size: var(--rail) !important; }
body.mark-moving .brand i { opacity: 0 !important; transition: none !important; }
/* each letter carries its own static under the fill, so the name can tune in and out one letter at a time (see handoff()) */
.brand b .lt:not(.spark-a), .me .lt:not(.spark-up), .me-dot.lt { background-image: var(--snow); background-size: calc(180px * var(--sk, 1)) calc(180px * var(--sk, 1)); -webkit-background-clip: text; background-clip: text; animation: snow .5s steps(6) infinite; }
.lt.st { -webkit-text-fill-color: transparent !important; }
.brand i { position: absolute; left: calc(100% + 3px); bottom: calc(var(--rail) * .5 * var(--trail-b, 0) - var(--trail-i, 0px)); writing-mode: vertical-rl; font: 700 min(12px, calc(var(--rail) * .24))/1 var(--title); font-stretch: 62%; font-style: normal; letter-spacing: .16em; text-transform: uppercase; color: var(--dim); white-space: nowrap; opacity: 0; transition: opacity .15s ease, color .4s; }
body[data-page]:not([data-page="home"]) .brand b, body.guiding .brand b { font-size: calc(var(--rail) * .5); }
body[data-page]:not([data-page="home"]) .brand > span, body.guiding .brand > span { position: absolute; opacity: 0; transition: none; }
/* while the mark grows back to full size on Home, DIGITAL waits out of sight and fades in once BELAL has settled */
body.mark-grow .brand > span { opacity: 0 !important; transition: none !important; }
/* going to or from Home, both DIGITALs switch off at once and come back in their new place once BELAL has resized */
body.dg-off .brand i, body.dg-off .brand > span { opacity: 0 !important; transition: none !important; }
body[data-page]:not([data-page="home"]) .brand i, body.guiding .brand i { opacity: 1; transition: opacity .4s ease .05s, color .4s; }
/* the pages sit in the middle: the same margin left and right, with BELAL in the left one and the menu in the right one,
   each the same distance from its edge */
@media (min-width: 761px) {
  .stage .channel { --side: calc(var(--rail) + max(48px, 6vw)); padding-left: var(--side); padding-right: var(--side); }
  .osd { padding-right: max(var(--edge-ink), env(safe-area-inset-right, 0px)); }
}
/* a page too tall for a short screen (zoomed right in) scrolls; what scrolls up fades out before it reaches the menu */
@media (min-width: 761px) {
  .stage .channel.scrolls { -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent 126px, #000 140px); mask-image: linear-gradient(to bottom, transparent 0, transparent 126px, #000 140px); }
}
@media (hover: hover) { .brand:hover span, .brand:hover i { color: var(--phosphor); } }
/* the A keeps its place in the word but isn't drawn; the sparkle A is laid over the same em box, turned with the word.
   Like the letters, it is static underneath (::before) with a solid fill on top (::after) that fades on the same timings */
.brand .spark-a { position: relative; visibility: hidden; }
.brand .spark-a::before, .brand .spark-a::after { content: ""; visibility: visible; position: absolute; left: 0; top: 0; width: 100%; height: .933em; }
.brand .spark-a::before { -webkit-mask: var(--spark-a) 0 0 / 100% 100% no-repeat; mask: var(--spark-a) 0 0 / 100% 100% no-repeat; }
.brand .spark-a::before { background-image: var(--snow); background-size: calc(180px * var(--sk, 1)) calc(180px * var(--sk, 1)); animation: snow .5s steps(6) infinite; }
.brand .spark-a::after { background: var(--spark-a-red) 0 0 / 100% 100% no-repeat; transition: opacity .8s ease; }
body.about-on .brand .spark-a::after { opacity: 0; transition: opacity .15s ease; }
@media (hover: hover) { .brand:hover b { animation: rgbsplit .6s steps(3) 1; } }
@keyframes rgbsplit {
  0% { text-shadow: 2px 0 rgba(255,70,60,.7), -2px 0 rgba(70,200,255,.7); }
  50% { text-shadow: -3px 0 rgba(255,70,60,.6), 3px 0 rgba(70,200,255,.6); transform: translateX(1px); }
  100% { text-shadow: 0 0 8px rgba(var(--glow), 0.45); transform: none; }
}
.brand:focus-visible, .burger:focus-visible { outline: 2px solid var(--phosphor); outline-offset: 4px; }

/* the menu: a plain stack of words down the right, each with a small round marker. Hovering a word fills its
   marker and the word re-forms out of static; the page you're on keeps a red marker */
.menu { display: grid; justify-items: end; gap: 10px; text-shadow: none; text-transform: none; }
.menu a { display: inline-flex; align-items: center; gap: 12px; font: 600 17px/1 var(--title); font-stretch: 110%; letter-spacing: .01em; color: var(--dim); text-decoration: none; transition: color .35s; }
.menu a .o { flex: none; width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid currentColor; transition: background-color .35s, border-color .35s, transform .5s var(--ease), box-shadow .35s; }
.menu a:focus-visible, .menu a[aria-current="true"] { color: var(--phosphor); }
@media (hover: hover) { .menu a:hover { color: var(--phosphor); } }
.menu a:focus-visible .o { background: currentColor; transform: scale(1.2); }
@media (hover: hover) { .menu a:hover .o { background: currentColor; transform: scale(1.2); } }
.menu a[aria-current="true"] .o { background: var(--live); border-color: var(--live); box-shadow: 0 0 10px rgba(var(--live-rgb), .7); }
.menu a:focus-visible { outline: none; text-decoration: underline; text-underline-offset: 5px; }
.menu a .w { display: inline-block; min-width: 0; }
/* below big screens the pages start right under the menu, so the stack sits a little tighter and ends above them.
   Its top stays level with the top of BELAL */
@media (min-width: 761px) and (max-width: 1399px), (min-width: 761px) and (max-height: 899px) {
  .menu { gap: 5px; }
  .menu a { font-size: 16px; }
}

.burger { display: none; width: 44px; height: 44px; background: none; border: 0; padding: 0; position: relative; }
.burger i { position: absolute; right: 8px; height: 2px; background: var(--phosphor); box-shadow: 0 0 8px rgba(var(--glow), .5); }
.burger i:nth-child(1) { top: 17px; width: 26px; }
.burger i:nth-child(2) { top: 26px; width: 15px; }


/* ---------- the picture ---------- */
.stage { position: fixed; inset: 0; z-index: 1; }

.channel {
  position: absolute; inset: 0; display: grid; align-content: safe center;
  padding: 140px var(--gr) clamp(76px, 13vh, 110px) var(--gl); overflow-y: auto; scrollbar-width: none; /* the bottom only needs room for the hint */
  visibility: hidden; opacity: 0;
}
.channel::-webkit-scrollbar { display: none; }
.channel.active { visibility: visible; opacity: 1; }
/* --fit is set by fitPages(): a page taller than the screen is scaled down to fit instead of scrolling */
.stage .channel > .inner { zoom: var(--fit, 1); }
.inner { position: relative; z-index: 1; width: 100%; max-width: 1180px; margin: 0 auto; display: grid; gap: clamp(18px, 2.6vw, 30px); }
.tag { margin: 0; font-family: var(--mono); font-weight: 500; font-size: 13px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--dim); }
h1, h2 {
  margin: 0; font-weight: 800; font-stretch: 125%; letter-spacing: -0.035em; line-height: 0.92; text-wrap: balance;
  color: var(--head); text-shadow: var(--fringe); transition: color .5s ease;
}
h1 { font-size: clamp(46px, 9.4vw, 150px); max-width: 12ch; }
h2 { font-size: clamp(36px, 5.6vw, 88px); max-width: 13ch; }
.static {
  color: transparent; -webkit-background-clip: text; background-clip: text;
  background-color: var(--phosphor); background-size: calc(180px * var(--sk, 1)) calc(180px * var(--sk, 1));
  animation: snow .5s steps(6) infinite; text-shadow: none; filter: drop-shadow(0 0 14px rgba(var(--glow), 0.25));
}
@keyframes snow { 0% { background-position: 0 0; } 100% { background-position: calc(540px * var(--sk, 1)) calc(360px * var(--sk, 1)); } }
/* ---------- home: the sentence is the picture. "static" is noise until you touch it; "signal" is clean and moving ---------- */
.hero { gap: clamp(30px, 4vw, 52px); }
/* the intro sits over the film: brighter text with a soft dark halo so it reads cleanly */
.hero .lede { color: color-mix(in srgb, var(--phosphor) 94%, transparent); text-shadow: 0 1px 14px rgba(19, 20, 18, .95), 0 0 2px rgba(19, 20, 18, .9); }
/* behind the headline: New York from the air at night, 1951 (US Army film, public domain). One shot at a time,
   picked at random, each dissolving into the next so the loop never cuts.
   Only the street lights come through, and a shade on the left keeps the words clean */
.hero-bg { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.hero-bg video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; mix-blend-mode: screen;
  filter: grayscale(1) contrast(1.4) brightness(.85); transition: opacity 1.8s ease; }
.hero-bg video.on { opacity: .75; }
.hero-bg::before { content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(100deg, rgba(19, 20, 18, .9) 6%, rgba(19, 20, 18, .55) 42%, rgba(19, 20, 18, 0) 78%), linear-gradient(to top, var(--screen), transparent 30%); }
/* the longest line ("static into signal.", about 9.5em) always fits the page width on one line */
.hero-h { display: grid; gap: .08em; max-width: none; font-size: min(clamp(40px, min(7.6vw, 12.5vh), 124px), calc((100vw - 2 * var(--side, 24px)) / 9.7)); line-height: .96; letter-spacing: -0.04em; }
.hero-h .ln { display: block; white-space: nowrap; }
.hero-h .static { -webkit-text-fill-color: transparent; }
.signal { position: relative; display: inline-block; color: var(--head); text-shadow: 0 0 28px rgba(var(--glow), .3); }
.sig-line { position: absolute; left: 0; right: 0; bottom: -.2em; width: 100%; height: .16em; overflow: visible; }
.sig-line path { fill: none; stroke: var(--head); stroke-width: 2.5; vector-effect: non-scaling-stroke; stroke-dasharray: 60 14; animation: flow 2.8s linear infinite; opacity: .85; }
@keyframes flow { to { stroke-dashoffset: -148; } }
@media (hover: hover) {
  .signal:hover .sig-line path { animation-duration: .8s; opacity: 1; filter: drop-shadow(0 0 4px rgba(var(--glow), .8)); }
}
.hero-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 28px 48px; max-width: 1120px; }
/* the call to action: a round button that leans toward the cursor and fills in when you reach it */
.talk-btn { display: inline-flex; align-items: center; gap: 18px; color: var(--phosphor); text-decoration: none; }
.tb-ring { position: relative; z-index: 1; display: grid; place-items: center; width: 76px; height: 76px; border-radius: 50%; border: 1px solid rgba(var(--glow), .35);
  transition: transform .5s var(--ease), background-color .4s ease, border-color .4s ease; will-change: transform; }
.tb-ring svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; transition: transform .5s var(--ease); }
.talk-btn:focus-visible .tb-ring { background: var(--phosphor); border-color: var(--phosphor); color: var(--screen); }
@media (hover: hover) { .talk-btn:hover .tb-ring { background: var(--phosphor); border-color: var(--phosphor); color: var(--screen); } }
@media (hover: hover) { .talk-btn:hover .tb-ring svg { transform: rotate(45deg); } }
.tb-txt { display: grid; gap: 6px; }
.tb-txt b { font-weight: 800; font-stretch: 125%; font-size: 20px; letter-spacing: -0.02em; }
.tb-txt span { font: 500 11px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--dim); }
.talk-btn:focus-visible { outline: 2px solid var(--phosphor); outline-offset: 6px; border-radius: 40px; }
/* running text is set in the body face; Archivo stays for headings, labels and buttons */
.lede, .note-lede, .note-body p, .note-body li, .a p, .steps p, .post-x, .fp-intro, .log li > span:last-child { font-family: var(--body); }
.lede { margin: 0; max-width: 44ch; font-size: clamp(17px, 1.45vw, 20px); font-weight: 400; line-height: 1.6; color: color-mix(in srgb, var(--phosphor) 82%, transparent); }
.note { margin: 0; font-family: var(--mono); font-size: 14px; line-height: 1.6; color: var(--dim); border: 1px dashed var(--line); padding: 10px 14px; max-width: 48ch; }
/* the LIVE light: a soft pulse with a ring that breathes out */
.rec { position: relative; display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: var(--live); margin-right: 9px; vertical-align: 1px; box-shadow: 0 0 8px rgba(var(--live-rgb), .8); }
/* the pulse is a ring that grows and fades: only scale and opacity move, which the GPU does without repainting */
.rec::after, .plot .now::after { content: ""; position: absolute; inset: 0; border-radius: 50%; box-shadow: 0 0 0 2px rgba(var(--live-rgb), .55); animation: ring 2.2s ease-out infinite; pointer-events: none; }
@keyframes ring { 0% { transform: scale(1); opacity: 1; } 60%, 100% { transform: scale(2.6); opacity: 0; } }
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(var(--live-rgb), 0.55), 0 0 8px rgba(var(--live-rgb), 0.8); opacity: 1; }
  60% { box-shadow: 0 0 0 9px rgba(var(--live-rgb), 0), 0 0 4px rgba(var(--live-rgb), 0.4); opacity: 0.7; }
  100% { box-shadow: 0 0 0 0 rgba(var(--live-rgb), 0), 0 0 8px rgba(var(--live-rgb), 0.8); opacity: 1; }
}

/* changing page: the picture blurs out and the new one sharpens in place; nothing moves */
.leave { animation: rollout .14s ease-out both; }
@keyframes rollout { to { opacity: 0; filter: blur(7px) brightness(1.8); } }
.tune { animation: tunein .7s var(--ease) both; }
@keyframes tunein {
  0%   { opacity: 0; filter: blur(8px) brightness(1.9); }
  45%  { opacity: 1; filter: blur(1.5px) brightness(1.2); }
  100% { opacity: 1; filter: none; }
}

/* ---------- work: laid out like a page of TV listings. The line-up of cases runs down the left, the one on now
   lit up as a solid block; the programme card for it fills the right. Labels use Archivo's narrowest cut, the same
   voice as DIGITAL in the mark ---------- */
.cond { font-family: var(--title); font-stretch: 62%; font-weight: 700; text-transform: uppercase; }
.listings { display: grid; grid-template-columns: minmax(240px, 290px) minmax(0, 1fr); gap: clamp(36px, 6vw, 96px); align-items: start; }
.lineup { display: grid; align-content: start; }
.lu-head { margin: 0; padding-bottom: 10px; border-bottom: 3px solid var(--phosphor);
  font: 700 15px/1 var(--title); font-stretch: 62%; letter-spacing: .14em; text-transform: uppercase; color: var(--phosphor); }
.row {
  position: relative; display: grid; grid-template-columns: 58px minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 12px; row-gap: 4px; align-items: end;
  margin: 0; padding: 16px 12px 15px; border: 0; border-bottom: 1px solid var(--line); background: none; font: inherit; color: var(--phosphor);
  text-align: left; text-decoration: none; isolation: isolate; transition: color .45s ease;
}
/* the highlight is a block that wipes in behind the row, like a listing marked with a pen */
.row::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--phosphor); transform: scaleY(0); transform-origin: bottom; transition: transform .55s var(--ease); }
.row.on::before { transform: none; }
.row.on { color: var(--screen); }
.row .n { grid-row: 1 / 3; font: 700 54px/.8 var(--title); font-stretch: 62%; letter-spacing: -.01em; color: var(--dim); transition: color .45s ease; }
.row.on .n { color: var(--screen); }
.row .t { font-weight: 800; font-stretch: 125%; font-size: 18px; line-height: 1.1; letter-spacing: -.02em; transition: transform .5s var(--ease); }
.row .s { display: inline-flex; align-items: center; gap: 7px; font: 700 13px/1 var(--title); font-stretch: 62%; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.row.on .s { color: color-mix(in srgb, var(--screen) 70%, transparent); }
.row .s .rec { width: 7px; height: 7px; margin: 0; }
.row:not(.on):focus-visible .t { transform: translateX(6px); }
@media (hover: hover) { .row:not(.on):hover .t { transform: translateX(6px); } }
.row:not(.on):focus-visible .n { color: var(--phosphor); }
@media (hover: hover) { .row:not(.on):hover .n { color: var(--phosphor); } }
.row:focus-visible { outline: 1px solid var(--phosphor); outline-offset: 2px; }
.row.open .s { color: var(--phosphor); }

.deck { display: grid; min-width: 0; }
.case { grid-area: 1 / 1; display: grid; gap: clamp(16px, 2.2vw, 24px); align-content: start; min-width: 0; }
.case:not(.on) { visibility: hidden; }
.kick { display: flex; align-items: center; gap: 2px; margin: 0; font: 700 15px/1 var(--title); font-stretch: 62%; letter-spacing: .14em; text-transform: uppercase; color: var(--phosphor); }
.kick { flex-wrap: wrap; row-gap: 8px; }
.kick .dim { color: var(--dim); white-space: nowrap; } /* the date and reading time move down together, never split */
@media (max-width: 760px) { .kick .dim:has(.sep) { flex-basis: 100%; } .kick .sep { display: none; } } /* on phones they take their own line */
/* the credits: who it's for, when it started, what the plan is */
.credits { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 0; border-top: 1px solid var(--line); }
.credits div { padding: 12px 16px 0 0; display: grid; gap: 6px; align-content: start; }
.credits div + div { padding-left: 16px; border-left: 1px solid var(--line); }
.credits dt { font: 700 13px/1 var(--title); font-stretch: 62%; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.credits dd { margin: 0; font-size: 16px; line-height: 1.35; color: var(--phosphor); }
/* the trace: a real chart frame with nothing faked in it. The line is flat at zero with a pulse at day 0;
   the dashed rest is time that hasn't happened yet */
.trace { margin: 0; display: grid; gap: 10px; }
.plot { position: relative; height: clamp(76px, 11vh, 110px); border-left: 1px solid rgba(var(--glow), .22);
  background: repeating-linear-gradient(to bottom, transparent 0 calc(33.33% - 1px), rgba(var(--glow), .15) calc(33.33% - 1px) 33.33%); }
.plot .future { position: absolute; left: 0; right: 0; bottom: 0; border-top: 1px dashed rgba(var(--glow), .28); }
.plot .run { position: absolute; left: 0; bottom: -1px; width: 6%; height: 2px; background: var(--phosphor); box-shadow: 0 0 8px rgba(var(--glow), .5); transform-origin: left; }
.plot .now { position: absolute; left: 6%; bottom: -5px; width: 10px; height: 10px; margin-left: -5px; border-radius: 50%; background: var(--live); box-shadow: 0 0 8px rgba(var(--live-rgb), .8); }
.plot .now b { position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%); font: 700 13px/1 var(--title); font-stretch: 62%; letter-spacing: .14em; text-transform: uppercase; color: var(--phosphor); white-space: nowrap; }
.case.rise .plot .run { animation: draw .9s var(--ease) .35s both; }
@keyframes draw { from { transform: scaleX(0); } }
.trace figcaption { display: flex; justify-content: space-between; gap: 16px; font: 700 13px/1.3 var(--title); font-stretch: 62%; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.trace figcaption span:last-child { text-align: right; }
/* the schedule: what aired, and what's on next */
.log { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.log li { display: grid; grid-template-columns: 96px 1fr; gap: 16px; align-items: baseline; }
.log time, .log .when { font: 700 14px/1.2 var(--title); font-stretch: 62%; letter-spacing: .12em; text-transform: uppercase; color: var(--phosphor); }
.log li > span:last-child { font-size: 16px; line-height: 1.5; color: color-mix(in srgb, var(--phosphor) 85%, transparent); }
.log li.next .when, .log li.next > span:last-child { color: var(--dim); }
/* the point on the chart: hover it (tap on a phone) and it grows, and its label says what happened that day */
.plot .now { cursor: default; outline: 1.5px solid transparent; outline-offset: 1px; transition: outline-color .3s ease, outline-offset .3s var(--ease); } /* picked: a ring, so the label never scales */
.plot .now::before { content: ""; position: absolute; inset: -12px; } /* a bigger target than the dot */
.plot .now b { display: grid; white-space: nowrap; left: -2px; transform: none; } /* the label starts at the point, so a long one runs into the chart, not off it */
.plot .now b > span { grid-area: 1 / 1; justify-self: start; transition: opacity .3s ease; }
.plot .now b .alt { opacity: 0; color: var(--phosphor); }
.plot .now.lit { outline-color: rgba(var(--live-rgb), .7); outline-offset: 4px; }
.plot .now.lit b > span:first-child { opacity: 0; }
.plot .now.lit b .alt { opacity: 1; }
@media (hover: hover) {
  .plot .now:hover { outline-color: rgba(var(--live-rgb), .7); outline-offset: 4px; }
  .plot .now:hover b > span:first-child { opacity: 0; }
  .plot .now:hover b .alt { opacity: 1; }
}

/* switching case: the old one dims away, the new one rises in a line at a time */
.case.cut-out { animation: cutout .24s ease-in both; }
@keyframes cutout { to { opacity: 0; filter: blur(4px); } }
.case.rise > * { animation: rise .8s var(--ease) both; animation-delay: calc(var(--i, 0) * 70ms); }
@keyframes rise { from { opacity: 0; transform: translateY(28px); filter: blur(6px); } to { opacity: 1; transform: none; filter: none; } }

/* ---------- about ---------- */
/* about: the bio on the left, the learning log on the right as a schedule (now, next, later), and a news crawl of
   what the work covers running along the bottom of the screen */
.about-inner { max-width: 1180px; display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); gap: clamp(36px, 6vw, 96px); align-items: start; }
.about-copy { max-width: 620px; display: grid; gap: clamp(16px, 2.2vw, 24px); align-content: start; }
/* a finished course reads as done: a tick, and the title steps back */
.learn { display: grid; gap: 14px; align-content: start; padding-top: 6px; }
.lg { list-style: none; margin: 0; padding: 0; display: grid; border-top: 3px solid var(--phosphor); }
.lg li { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 14px; align-items: baseline; padding: 14px 0; border-bottom: 1px solid var(--line); }
.lg-s { font: 700 14px/1 var(--title); font-stretch: 62%; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.lg-s.now { color: var(--live); }
.lg li.done .lg-s { color: #5fd38a; }
.lg li.done .lg-t { color: var(--dim); }
.lg-t { display: grid; gap: 5px; font-weight: 800; font-stretch: 125%; font-size: 17px; line-height: 1.2; letter-spacing: -.02em; color: var(--phosphor); }
.lg-src { display: grid; }
.lg-src small { grid-area: 1 / 1; transition: opacity .3s ease, transform .3s var(--ease); }
.lg-src .why { color: var(--phosphor); opacity: 0; transform: translateY(4px); }
@media (hover: hover) {
  .lg li:hover .lg-src small:first-child { opacity: 0; transform: translateY(-4px); }
  .lg li:hover .lg-src .why { opacity: 1; transform: none; }
}
.lg-t small { font: 700 13px/1 var(--title); font-stretch: 62%; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
/* About keeps its content clear of the crawl: room for the crawl plus the same gap as everywhere else */
.stage .channel#about { padding-bottom: 136px; }
.crawl { position: absolute; left: 0; right: 0; bottom: 58px; display: flex; height: 38px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); overflow: hidden; }
.crawl-label { flex: none; display: grid; place-items: center; padding: 0 16px; background: var(--live); color: #1a0503; font: 700 14px/1 var(--title); font-stretch: 62%; letter-spacing: .14em; text-transform: uppercase; }
.crawl-view { flex: 1; overflow: hidden; display: flex; align-items: center; -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent); mask-image: linear-gradient(90deg, #000 85%, transparent); }
.crawl-track { display: flex; flex: none; animation: crawl 45s linear infinite; }
.crawl-track span { display: inline-flex; align-items: center; white-space: nowrap; padding: 0 22px; font-weight: 800; font-stretch: 125%; font-size: 15px; letter-spacing: -.01em; color: var(--phosphor); }
.crawl-track span::after { content: ""; width: 5px; height: 5px; margin-left: 44px; border-radius: 50%; background: var(--dim); }
@keyframes crawl { to { transform: translateX(-50%); } }
/* on About, BELAL leaves the mark and becomes the name in the heading; DIGITAL fades while it's away */
/* on About, BELAL in the mark breaks up into static and fades, and the BELAL in the heading tunes in out of the same
   static before settling solid. Moving on, the mark tunes back in the same way */
.me { text-transform: uppercase; opacity: 0; -webkit-text-fill-color: transparent; transition: opacity .35s ease, -webkit-text-fill-color .9s ease; }
.me.tuning { opacity: 1; }
.me.landed { opacity: 1; -webkit-text-fill-color: var(--head); }
.me-dot { opacity: 0; transition: opacity .3s ease; }
.me.landed + .me-dot { opacity: 1; }
.me.instant, .me.instant .spark-up::after, .me.instant + .me-dot { transition: none !important; }
/* the flight: a copy of BELAL lifts off the sideways mark, turns upright and lands in the heading (and back) */
.me { display: inline-block; transform-origin: 50% 52%; }
/* the handoff between the mark and the heading: letter by letter, the name goes to static in one place and comes up
   out of static in the other (see handoff() in the script) */
body.handoff .brand b { -webkit-text-fill-color: var(--phosphor) !important; opacity: 1 !important; }
/* on hover the whole word, A included, splits into red and blue for a moment, like a TV losing and finding the picture */
@keyframes rgbsplit-a {
  0% { filter: drop-shadow(2px 0 rgba(255,70,60,.7)) drop-shadow(-2px 0 rgba(70,200,255,.7)); }
  50% { filter: drop-shadow(-3px 0 rgba(255,70,60,.6)) drop-shadow(3px 0 rgba(70,200,255,.6)); }
  100% { filter: none; }
}
@media (hover: hover) { .brand:hover .spark-a::after { animation: rgbsplit-a .6s steps(3) 1; } }
body.handoff .brand .spark-a::after { opacity: 1 !important; transition: none !important; }
body.handoff .brand .spark-a.st::after, .me .spark-up.st::after { opacity: 0 !important; }
/* its A is the sparkle A, upright: static while the name tunes in, then cream with the red sparkle as it lands */
:root { --spark-up: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 933 1088'%3E%3Cpath fill-rule='evenodd' d='M15,878 L352,190.5 L580,190.5 L921,878 L697,878 L468,728 L224,878Z M468.2,305.4 C468.2,389.6 546.6,477.3 635,477.3 C543.3,477.3 468.2,568.8 468.2,640.6 C468.2,578.6 400.5,477.3 299,477.3 C383.6,477.3 468.2,401.7 468.2,305.4Z'/%3E%3C/svg%3E");
  --spark-up-red: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 933 1088'%3E%3Cpath fill='%23efeadf' fill-rule='evenodd' d='M15,878 L352,190.5 L580,190.5 L921,878 L697,878 L468,728 L224,878Z M468.2,305.4 C468.2,389.6 546.6,477.3 635,477.3 C543.3,477.3 468.2,568.8 468.2,640.6 C468.2,578.6 400.5,477.3 299,477.3 C383.6,477.3 468.2,401.7 468.2,305.4Z'/%3E%3Cpath fill='%23ff5a4e' d='M468.2,305.4 C468.2,389.6 546.6,477.3 635,477.3 C543.3,477.3 468.2,568.8 468.2,640.6 C468.2,578.6 400.5,477.3 299,477.3 C383.6,477.3 468.2,401.7 468.2,305.4Z'/%3E%3C/svg%3E"); }
.me .spark-up { position: relative; visibility: hidden; }
.me .spark-up::before, .me .spark-up::after { content: ""; visibility: visible; position: absolute; left: 0; top: 0; width: .933em; height: 100%; }
.me .spark-up::before { background-image: var(--snow); background-size: calc(180px * var(--sk, 1)) calc(180px * var(--sk, 1)); animation: snow .5s steps(6) infinite;
  -webkit-mask: var(--spark-up) 0 0 / 100% 100% no-repeat; mask: var(--spark-up) 0 0 / 100% 100% no-repeat; }
.me .spark-up::after { background: var(--spark-up-red) 0 0 / 100% 100% no-repeat; opacity: 0; transition: opacity .9s ease; }
.me.landed .spark-up::after { opacity: 1; }
body.about-on .brand b { -webkit-text-fill-color: transparent; opacity: 0; transition: -webkit-text-fill-color .15s ease, opacity .6s ease .3s; }
body.about-on[data-page] .brand > span, body.about-on[data-page] .brand i { opacity: 0; transition: opacity .3s ease; }
/* with the phone menu open on About, the mark shows as on any other page */
body.about-on.guiding .brand b { -webkit-text-fill-color: var(--phosphor); opacity: 1; }
body.about-on.guiding .brand i { opacity: 1; }
body.about-on.guiding .brand .spark-a::after { opacity: 1; }

/* ---------- contact: the page invites; the form itself slides in over whatever is on screen ---------- */
/* ---------- questions: the page header on the left, the answers on the right. One question opens at a time,
   folding down like a listing being read out ---------- */
/* ---------- playbook: the sections down the left like the Work line-up, the open one on the right ---------- */
.pb-inner { display: grid; grid-template-columns: minmax(230px, 300px) minmax(0, 1fr); gap: clamp(36px, 6vw, 96px); align-items: start; }
.pb-side { display: grid; gap: clamp(16px, 2.2vw, 24px); align-content: start; }
.pb-side h2 { font-size: clamp(36px, 4.4vw, 66px); max-width: 8ch; }
.tabs { display: grid; margin-top: 6px; border-top: 3px solid var(--phosphor); }
.tab { position: relative; isolation: isolate; display: flex; align-items: baseline; gap: 14px; padding: 15px 12px; border-bottom: 1px solid var(--line); text-align: left;
  font-weight: 800; font-stretch: 125%; font-size: 18px; letter-spacing: -.02em; color: var(--dim); transition: color .45s ease; }
.tab .tn { font: 700 15px/1 var(--title); font-stretch: 62%; letter-spacing: .12em; }
.tab::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--phosphor); transform: scaleY(0); transform-origin: bottom; transition: transform .55s var(--ease); }
.tab[aria-selected="true"] { color: var(--screen); }
.tab[aria-selected="true"]::before { transform: none; }
@media (hover: hover) { .tab:not([aria-selected="true"]):hover { color: var(--phosphor); } }
.tab:focus-visible { outline: 1px solid var(--phosphor); outline-offset: 2px; }
.pb-panes { display: grid; min-width: 0; }
.pb-pane { grid-area: 1 / 1; display: grid; gap: clamp(18px, 2.4vw, 28px); align-content: start; min-width: 0; }
.pb-pane:not(.on) { visibility: hidden; }
.pb-pane.on > * { animation: rise .7s var(--ease) both; }
.pb-pane.on > :nth-child(2) { animation-delay: .07s; } .pb-pane.on > :nth-child(3) { animation-delay: .14s; }
.pb-pane .btn { justify-self: start; }
/* how I work: four steps in a two by two grid */
.steps { position: relative; list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
/* the job runs down a rail: when on the left, a sparkle on the line, what happens on the right. The last stop keeps going.
   Rail and sparkles share one centre line, the middle of the 19px column: an odd width, and a whole-pixel start, so the
   1px rail and the 13px sparkle both sit on the same pixel instead of being rounded apart */
.steps::before { content: ""; position: absolute; left: calc(var(--when) + var(--gap)); width: 19px; top: 22px; bottom: 26px;
  background: linear-gradient(color-mix(in srgb, var(--phosphor) 30%, transparent), color-mix(in srgb, var(--phosphor) 30%, transparent)) 50% 0 / 1px 100% no-repeat; }
.steps { --when: clamp(84px, 9vw, 112px); --gap: 18px; }
@supports (width: round(1px, 1px)) { .steps { --when: round(clamp(84px, 9vw, 112px), 1px); } }
.steps li { position: relative; display: grid; grid-template-columns: var(--when) 19px minmax(0, 1fr); column-gap: var(--gap); align-items: baseline; padding: 14px 0; }
.steps li::before { content: ""; grid-column: 2; grid-row: 1; justify-self: stretch; align-self: center; height: 13px; background: var(--dim);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1 -1 102 102'%3E%3Cpath d='M50.4,0.1 C50.4,25.2 73.7,51.3 100,51.3 C72.7,51.3 50.4,78.5 50.4,99.9 C50.4,81.4 30.2,51.3 0,51.3 C25.2,51.3 50.4,28.8 50.4,0.1Z'/%3E%3C/svg%3E") 50% 50% / 13px 13px no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1 -1 102 102'%3E%3Cpath d='M50.4,0.1 C50.4,25.2 73.7,51.3 100,51.3 C72.7,51.3 50.4,78.5 50.4,99.9 C50.4,81.4 30.2,51.3 0,51.3 C25.2,51.3 50.4,28.8 50.4,0.1Z'/%3E%3C/svg%3E") 50% 50% / 13px 13px no-repeat; }
.steps li.ongoing::before { background: var(--live); filter: drop-shadow(0 0 5px rgba(var(--live-rgb), .8)); }
.steps .sn { grid-column: 1; grid-row: 1; font: 700 15px/1 var(--title); font-stretch: 62%; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.steps li.ongoing .sn { color: var(--live); }
.steps h3 { grid-column: 3; grid-row: 1; margin: 0; font-weight: 800; font-stretch: 125%; font-size: 19px; letter-spacing: -.02em; color: var(--phosphor); }
.steps p { grid-column: 3; margin-top: 6px !important; }
.steps p { margin: 0; font-size: 15px; line-height: 1.55; color: color-mix(in srgb, var(--phosphor) 75%, transparent); }
/* writing: each note is one listing; it opens in a reading sheet */
.post { display: grid; gap: 12px; padding: 20px 0 22px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); color: var(--phosphor); text-decoration: none; }
.post-meta { font: 700 14px/1 var(--title); font-stretch: 62%; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.post-t { font-weight: 800; font-stretch: 125%; font-size: clamp(24px, 2.6vw, 38px); line-height: 1.05; letter-spacing: -.03em; max-width: 22ch; transition: transform .5s var(--ease); }
.post-x { max-width: 56ch; font-size: 16px; line-height: 1.6; color: color-mix(in srgb, var(--phosphor) 75%, transparent); }
.post-go { display: inline-flex; align-items: center; gap: 10px; font: 800 15px/1 var(--title); font-stretch: 112%; }
.post-go svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; transition: transform .4s var(--ease); }
.post:focus-visible .post-t { transform: translateX(6px); }
@media (hover: hover) { .post:hover .post-t { transform: translateX(6px); } }
.post:focus-visible .post-go svg { transform: translateX(4px); }
@media (hover: hover) { .post:hover .post-go svg { transform: translateX(4px); } }
.post:focus-visible { outline: 1px solid var(--phosphor); outline-offset: 6px; }
/* the reading sheet: one column, set for reading */
.reader .fp-body { display: block; width: 100%; max-width: 820px; margin: 0 auto; }
.note-body > * + * { margin-top: 18px; }
.reader .note-body h2 { font-size: clamp(32px, 3.4vw, 54px); max-width: 20ch; }
.note-lede { margin: 0; font-size: clamp(18px, 1.5vw, 21px); line-height: 1.55; color: color-mix(in srgb, var(--phosphor) 92%, transparent); }
.note-body h3 { margin: 34px 0 0; font-weight: 800; font-stretch: 125%; font-size: 20px; letter-spacing: -.02em; color: var(--phosphor); }
.note-body p, .note-body li { max-width: 62ch; font-size: 17px; line-height: 1.7; color: color-mix(in srgb, var(--phosphor) 80%, transparent); }
.note-body h3 + p { margin-top: 10px; }
.note-body ul { margin-left: 0; padding-left: 1.1em; }
.note-body li + li { margin-top: 8px; }
.note-body li::marker { color: var(--dim); }
.note-body .byline { margin-top: 20px; font: 700 14px/1.4 var(--title); font-stretch: 62%; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.note-body .byline + * { margin-top: 30px; }
.note-body a { color: var(--phosphor); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
@media (hover: hover) { .note-body a:hover { text-decoration-thickness: 2px; } }
/* how to reach me, beside the form */
.fp-reach { display: grid; align-content: start; margin-top: 10px; border-top: 1px solid var(--line); } /* rows hug their links (they used to stretch to the form's height) */
.rch { display: grid; grid-template-columns: 76px 1fr; gap: 12px; align-items: start; padding: 14px 0; border-bottom: 1px solid var(--line); }
.rch .rl { padding-top: 3px; } /* lines the small label up with the first link, without baseline alignment's extra height */
.rl { font: 700 14px/1 var(--title); font-stretch: 62%; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.rv { font-size: 16px; color: var(--dim); }
.socials { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.socials a { display: flex; justify-content: space-between; align-items: center; gap: 12px; font-size: 16px; color: var(--phosphor); text-decoration: none; overflow-wrap: anywhere; }
.socials a:hover, .socials a:focus-visible { color: var(--phosphor); }
.socials svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; transition: transform .4s var(--ease); }
.socials a:focus-visible svg { transform: translateX(4px); }
@media (hover: hover) { .socials a:hover svg { transform: translateX(4px); } }
.form-panel.open .fp-body > :nth-child(5) { transition-delay: .78s; }
.faq { border-top: 1px solid var(--line); }
.qa { border-bottom: 1px solid var(--line); }
.q { display: grid; grid-template-columns: 44px minmax(0, 1fr) 22px; align-items: baseline; gap: 12px; width: 100%; padding: 18px 0; text-align: left; color: var(--phosphor); }
.q .qn { font: 700 15px/1 var(--title); font-stretch: 62%; letter-spacing: .12em; color: var(--dim); transition: color .3s; }
.q .qt { font-weight: 800; font-stretch: 125%; font-size: clamp(17px, 1.5vw, 21px); line-height: 1.2; letter-spacing: -.02em; transition: transform .5s var(--ease); }
.q .qi { position: relative; align-self: center; width: 14px; height: 14px; justify-self: end; }
.q .qi::before, .q .qi::after { content: ""; position: absolute; left: 0; top: 50%; width: 100%; height: 1.5px; margin-top: -.75px; background: currentColor; transition: transform .5s var(--ease); }
.q .qi::after { transform: rotate(90deg); }
.q[aria-expanded="true"] .qi::after { transform: rotate(0); }
.q:focus-visible .qt { transform: translateX(6px); }
@media (hover: hover) { .q:hover .qt { transform: translateX(6px); } }
.q[aria-expanded="true"] .qn { color: var(--live); }
@media (hover: hover) { .q:hover .qn { color: var(--live); } }
.q:focus-visible { outline: 1px solid var(--phosphor); outline-offset: 4px; }
.a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .55s var(--ease); }
.a > div { min-height: 0; overflow: hidden; }
.a p { margin: 0; padding: 0 22px 20px 56px; max-width: 60ch; font-size: 16px; line-height: 1.6; color: color-mix(in srgb, var(--phosphor) 78%, transparent); }
.qa.open .a { grid-template-rows: 1fr; }

/* a plain button: solid, square, an arrow that nudges on hover */
.btn { display: inline-flex; align-items: center; gap: 12px; padding: 15px 22px; border: 1px solid var(--phosphor); background: var(--phosphor); color: var(--screen);
  font: 800 16px/1 var(--title); font-stretch: 112%; letter-spacing: -.01em; text-decoration: none; cursor: pointer; transition: background-color .3s, color .3s; }
.btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; transition: transform .4s var(--ease); }
.btn:focus-visible { background: transparent; color: var(--phosphor); outline: none; }
@media (hover: hover) { .btn:hover { background: transparent; color: var(--phosphor); outline: none; } }
.btn:focus-visible svg { transform: translateX(4px); }
@media (hover: hover) { .btn:hover svg { transform: translateX(4px); } }
button.btn:focus-visible { background-color: transparent; color: var(--phosphor); }
@media (hover: hover) { button.btn:hover { background-color: transparent; color: var(--phosphor); } }

.form-panel { position: fixed; inset: 0; z-index: 46; visibility: hidden; transition: visibility 0s linear 1s; }
.form-panel.open { visibility: visible; transition: visibility 0s; }
.fp-shade { position: absolute; inset: 0; background: rgba(8, 8, 7, .62); opacity: 0; transition: opacity .9s ease; }
.form-panel.open .fp-shade { opacity: 1; }
.fp-sheet { position: absolute; top: 0; right: 0; bottom: 0; width: 75vw; background: #1a1b18;
  transform: translateX(calc(100% + 30px)); transition: transform .95s cubic-bezier(.76, 0, .24, 1); }
.form-panel.open .fp-sheet { transform: none; }
/* the sheet arrives with a bright edge, like a picture being drawn in by the beam, which then settles to a hairline */
.fp-sheet::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 1px; background: rgba(var(--glow), .2); }
.fp-sheet::after { content: ""; position: absolute; left: -1px; top: 0; bottom: 0; width: 3px; background: var(--phosphor); box-shadow: 0 0 18px 4px rgba(var(--glow), .45), 0 0 60px 12px rgba(var(--glow), .15); opacity: 0; }
.form-panel.open .fp-sheet::after { animation: edgefade 1.4s ease .2s both; }
@keyframes edgefade { 0%, 45% { opacity: 1; } 100% { opacity: 0; } }
/* on a wide sheet the heading sits on the left and the form on the right */
@media (min-width: 901px) {
  .fp-body { grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); grid-template-rows: auto auto auto 1fr; column-gap: clamp(36px, 5vw, 80px); align-content: start; }
  .fp-body > :not(form) { grid-column: 1; }
  .fp-form { grid-column: 2; grid-row: 1 / span 4; margin-top: 0; }
}
.fp-scroll { position: absolute; inset: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; }
.fp-scroll::-webkit-scrollbar { display: none; }
.fp-body { display: grid; gap: clamp(16px, 2.2vw, 24px); padding: clamp(84px, 13vh, 130px) clamp(28px, 5vw, 76px) 60px; }
.fp-body h2 { font-size: clamp(44px, 5vw, 80px); }
.fp-intro { margin: 0; max-width: 40ch; font-size: clamp(16px, 1.3vw, 19px); line-height: 1.55; color: color-mix(in srgb, var(--phosphor) 80%, transparent); }
.fp-form { display: grid; gap: 22px; margin-top: 8px; }
.fld { display: grid; gap: 8px; }
.fld > span { font: 700 14px/1 var(--title); font-stretch: 62%; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); transition: color .3s; }
.fld em { font-style: normal; opacity: .6; margin-left: 6px; }
.fld input, .fld textarea { width: 100%; margin: 0; padding: 6px 0 10px; border: 0; border-bottom: 1px solid rgba(var(--glow), .25); border-radius: 0; background: none;
  font: 400 clamp(18px, 1.5vw, 21px)/1.4 var(--title); color: var(--phosphor); outline: none; resize: vertical; transition: border-color .3s, box-shadow .3s; }
.fld textarea { min-height: 3.2em; }
.fld input::placeholder { color: rgba(var(--glow), .25); }
.fld:focus-within > span { color: var(--phosphor); }
.fld input:focus, .fld textarea:focus { border-bottom-color: var(--phosphor); box-shadow: 0 1px 0 var(--phosphor); }
.fld.bad > span { color: var(--live); }
.fld.bad input, .fld.bad textarea { border-bottom-color: var(--live); }
.fp-send { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 28px; margin-top: 10px; }
/* send: a wide transmit bar. A level meter idles on the right; on hover the bar floods with light from the left,
   the meter jumps, and the words invert */

.fp-status { margin: 0; max-width: 34ch; font-size: 14px; line-height: 1.5; color: var(--dim); }
/* the sheet's only footer: a name and a year in the corner */
/* the sheet's only footer: the name in one bottom corner, the year in the other. It sits at the bottom of the sheet,
   or after the form when the form runs longer than the screen */
.fp-scroll { display: flex; flex-direction: column; }
.fp-body { flex: none; }
.fp-name { display: inline-flex; align-items: center; gap: .6em; }
.fp-star { display: inline-block; font-size: 1.15em; line-height: 1; letter-spacing: 0; color: var(--live); cursor: pointer; }
.fp-star.spin { animation: spin .8s var(--ease) 1; }
@keyframes spin { to { transform: rotate(360deg); } }
.fp-foot { margin-top: auto; display: flex; justify-content: space-between; gap: 16px; padding: 0 clamp(28px, 5vw, 76px) 24px;
  font: 700 13px/1 var(--title); font-stretch: 62%; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.fp-close { position: absolute; z-index: 2; top: clamp(20px, 3vh, 30px); right: clamp(20px, 3vw, 34px); width: 54px; height: 54px; border-radius: 50%; border: 1px solid rgba(var(--glow), .3);
  background: none; padding: 0; color: var(--phosphor); transition: background-color .35s, color .35s, transform .5s var(--ease); }
.fp-close i { position: absolute; left: 50%; top: 50%; width: 20px; height: 1.5px; margin: -.75px 0 0 -10px; background: currentColor; transform: rotate(45deg); }
.fp-close i + i { transform: rotate(-45deg); }
.fp-close:focus-visible { background: var(--phosphor); color: var(--screen); transform: rotate(90deg); outline: none; }
@media (hover: hover) { .fp-close:hover { background: var(--phosphor); color: var(--screen); transform: rotate(90deg); outline: none; } }
/* the copy follows the sheet in, a line at a time */
.fp-body > * { opacity: 0; transform: translateY(24px); transition: opacity .3s ease, transform .3s ease; }
.form-panel.open .fp-body > * { opacity: 1; transform: none; transition: opacity .7s ease, transform .9s var(--ease); }
.form-panel.open .fp-body > :nth-child(1) { transition-delay: .5s; } .form-panel.open .fp-body > :nth-child(2) { transition-delay: .57s; }
.form-panel.open .fp-body > :nth-child(3) { transition-delay: .64s; } .form-panel.open .fp-body > :nth-child(4) { transition-delay: .71s; }

/* ---------- the tube: scanlines, grain, hum bar, edge falloff ---------- */
.tube { position: fixed; inset: 0; z-index: 50; pointer-events: none; }
.tube .lines { position: absolute; inset: 0; opacity: .72; background: repeating-linear-gradient(to bottom, rgba(0,0,0,0) 0 calc(var(--scan, 3px) * 2 / 3), rgba(0,0,0,0.22) calc(var(--scan, 3px) * 2 / 3) var(--scan, 3px)); }
/* laptops and tablets sit between the big screen and the phone: lighter lines */
@media (min-width: 761px) and (max-width: 1399px) { .tube .lines { opacity: .45; } }
.tube .grain { position: absolute; inset: -12%; opacity: 0.03; background-size: calc(180px * var(--zk, 1)) calc(180px * var(--zk, 1)); animation: grain .4s steps(5) infinite; transition: opacity .8s ease; }
/* a faint film, barely there: fainter still on phones, and only a trace over the plain dark of the cold open */
@media (max-width: 760px) { .tube .grain { opacity: 0.022; } }
body:has(#intro) .tube .grain { opacity: 0.01; }
/* light mode (html.lite), only with ?lite in the address, for testing slow phones. Anything that makes the phone redraw the screen over and over is turned off: the film rests on its
   still frame, the tube overlay, grain and page flicker go, the static holds still, glows and colour fringes go, and page
   changes fade without blur. At a glance it is the same site */
.lite .tube { display: none; }
.lite body.flicker { animation: none; }
.lite * { text-shadow: none !important; }
.lite .hero-bg video { mix-blend-mode: normal; filter: none; }
.lite .hero-bg video.on { opacity: .42; }
.lite .static { filter: none; }
.lite .static, .lite .lt, .lite .brand .spark-a::before, .lite .me .spark-up::before, .lite .g-list a[aria-current="true"] .nm, .lite .sig-line path { animation: none; }
.lite .stage .channel, .lite .crawl-view { -webkit-mask-image: none !important; mask-image: none !important; }
.lite .burst.on { animation: burst .46s ease-out; } .lite .burst.soft.on { animation: burstsoft .5s ease-out; }
.lite .leave { animation-name: fadeout; } .lite .tune { animation-name: fadein; }
.lite .case.cut-out { animation-name: fadeout; } .lite .case.rise > *, .lite .pb-pane.on > * { animation-name: fadein; }
@keyframes fadeout { to { opacity: 0; } }
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
/* work saved on every frame, nothing visible lost: pages off screen hold still, and static hidden under a solid
   fill (the mark, the About name once it has landed) doesn't run */
.stage .channel:not(.active) *, .stage .channel:not(.active) *::before, .stage .channel:not(.active) *::after { animation-play-state: paused !important; }
.guide:not(.open) *, .form-panel:not(.open) *, .form-panel:not(.open) *::before, .form-panel:not(.open) *::after { animation-play-state: paused !important; } /* closed menu and sheets too */
.brand .lt, .brand .spark-a::before { animation-play-state: paused; }
.me.landed .lt, .me.landed .spark-up::before, .me-dot.lt { animation-play-state: paused; }
body.handoff .lt, body.handoff .spark-a::before, body.handoff .spark-up::before { animation-play-state: running !important; }
@keyframes grain { 0% { transform: translate(0,0); } 25% { transform: translate(-7%,4%); } 50% { transform: translate(5%,-6%); } 75% { transform: translate(-3%,-8%); } 100% { transform: translate(6%,3%); } }
@keyframes hum { to { transform: translateY(124vh); } }
.tube .shine { position: absolute; inset: 0; background:
  radial-gradient(70% 45% at 28% 8%, rgba(255,255,255,0.03), transparent 70%),
  radial-gradient(150% 120% at 50% 50%, transparent 58%, rgba(0,0,0,0.45) 100%); }
body.blink { opacity: .96; } /* one frame, every few seconds (see the script) */
@keyframes flicker { 0%, 100% { opacity: 1; } 47% { opacity: 1; } 48% { opacity: 0.96; } 49% { opacity: 1; } }

.burst { position: fixed; inset: 0; z-index: 60; pointer-events: none; opacity: 0; background-color: #6d6a63; background-size: calc(180px * var(--zk, 1)) calc(180px * var(--zk, 1)); background-blend-mode: multiply; }
.burst.on { animation: burst .46s ease-out, snow .2s steps(4) infinite; }
.burst.soft.on { animation: burstsoft .5s ease-out, snow .2s steps(4) infinite; }
@keyframes burst { 0% { opacity: 0; } 18% { opacity: 1; } 55% { opacity: 1; } 100% { opacity: 0; } }
@keyframes burstsoft { 0% { opacity: 0; } 30% { opacity: 0.32; } 100% { opacity: 0; } }

@keyframes powerfade { to { opacity: 0; visibility: hidden; } }

/* ---------- phone menu: the screen rises from the bottom (slow, fast, slow) with a bright scan line on its top edge.
   Big wide words; the page you're on is written in static, like "static" on the home page. The mark and the
   button stay on top, and the button turns into a close X ---------- */
.guide {
  position: fixed; z-index: 39; inset: 0; display: flex; flex-direction: column;
  background: #1a1b18; transform: translateY(101%); visibility: hidden;
  transition: transform .95s cubic-bezier(.76, 0, .24, 1), visibility 0s linear .95s;
}
.guide::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px; background: var(--phosphor);
  box-shadow: 0 0 18px 4px rgba(var(--glow), .45), 0 0 60px 10px rgba(var(--glow), .15); opacity: 0; transition: opacity .4s ease .7s; }
.guide.open { transform: none; visibility: visible; transition: transform .95s cubic-bezier(.76, 0, .24, 1), visibility 0s; }
.guide.open::before { opacity: 1; animation: scanfade 1.1s ease both; }
@keyframes scanfade { 0%, 60% { opacity: 1; } 100% { opacity: 0; } }
.guide { --g-top: max(calc(var(--mrail, 13vw) * 2.2 + 70px), 94px); }
/* the menu scrolls when the screen is too short for it (zoomed right in); what scrolls up fades out below the mark */
.g-scroll { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none;
  padding: calc(var(--g-top) + env(safe-area-inset-top, 0px)) var(--gr) calc(26px + env(safe-area-inset-bottom, 0px)) var(--gl);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent calc(var(--g-top) - 22px), #000 calc(var(--g-top) - 2px));
  mask-image: linear-gradient(to bottom, transparent 0, transparent calc(var(--g-top) - 22px), #000 calc(var(--g-top) - 2px)); }
.g-scroll::-webkit-scrollbar { display: none; }
.g-list { list-style: none; margin: 0; padding: 0; display: grid; }
.g-list li { overflow: hidden; border-bottom: 1px solid var(--line); }
.g-list li:first-child { border-top: 1px solid var(--line); }
.g-list a { display: flex; justify-content: space-between; align-items: baseline; padding: 12px 0 10px; color: var(--phosphor); text-decoration: none;
  transform: translateY(105%); transition: transform .35s ease; }
.g-list .nm { font: 800 clamp(22px, min(12.5vw, 8vh), 60px)/.95 var(--title); font-stretch: 125%; letter-spacing: -0.04em; text-transform: uppercase; }
.g-list a[aria-current="true"] .nm { color: transparent; -webkit-background-clip: text; background-clip: text; background-color: var(--phosphor); background-image: var(--snow); background-size: calc(180px * var(--sk, 1)) calc(180px * var(--sk, 1)); animation: snow .5s steps(6) infinite; }
.g-list a:active .nm { opacity: .6; }
/* the page on screen is lit (static, with the red on-air light); the others step back */
.g-list a:not([aria-current="true"]) .nm { color: rgba(var(--glow), .42); }
.g-list a[aria-current="true"]::after { content: ""; align-self: center; flex: none; width: 12px; height: 12px; border-radius: 50%; background: var(--live); box-shadow: 0 0 12px rgba(var(--live-rgb), .8); }
.guide.open .g-list a { transform: none; transition: transform .9s var(--ease); transition-delay: calc(.5s + var(--k, 0) * 70ms); }
.g-foot { margin-top: auto; padding-top: 24px; display: flex; justify-content: space-between; align-items: flex-end; gap: 16px; opacity: 0; transition: opacity .3s; }
.guide.open .g-foot { opacity: 1; transition: opacity .8s ease .85s; }
.g-foot p { margin: 0; max-width: 20ch; font: 500 11px/1.6 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--dim); }
.g-foot .talk-btn { gap: 14px; }
.g-foot .tb-ring { width: 58px; height: 58px; }
.g-foot .talk-btn:active .tb-ring { background: var(--phosphor); color: var(--screen); }
body.guiding .burger i:nth-child(1) { top: 21px; transform: rotate(45deg); width: 24px; }
body.guiding .burger i:nth-child(2) { top: 21px; transform: rotate(-45deg); width: 24px; }
.burger i { transition: transform .6s var(--ease), width .6s var(--ease), top .6s var(--ease); }

@media (max-width: 900px) {
  .listings { grid-template-columns: 1fr; gap: 26px; }
  .pb-inner { grid-template-columns: 1fr; gap: 22px; }
  /* once the tabs sit above the content, the content gets no rule of its own under them: same for all three */
  .pb-side h2 { max-width: none; }
  .a p { padding-left: 0; }
  .lineup { order: 2; }
  @media (min-width: 761px) { .stage .channel { --side: calc(var(--rail) + 36px); } }
  /* under the case, the line-up is a strip of small listings, as on phones */
  .lineup { display: flex; border-top: 3px solid var(--phosphor); }
  .lu-head { display: none; }
  .row { flex: 1 0 auto; grid-template-columns: auto auto; justify-content: center; column-gap: 10px; align-items: center; padding: 14px 12px 10px; border-bottom: 0; border-right: 1px solid var(--line); }
  .row:last-child { border-right: 0; }
  .row .n { grid-row: auto; font-size: 30px; line-height: 1; }
  .row .t { font-size: 15px; line-height: 1; white-space: nowrap; }
  .row .s { display: none; }
  /* stacked above the content, the tabs sit in one row, as on phones */
  .tabs { display: flex; }
  .tab { flex: 1 0 auto; justify-content: center; border-bottom: 0; }
}
@media (max-width: 760px) {
  /* the phone mark scales with the screen, but stops growing on mid-size screens so pages keep their room */
  :root { --mrail: min(13vw, 60px, 10vh); } /* and on a short screen (a laptop zoomed right in) it shrinks with the height too */
  .osd { display: grid; grid-template-columns: 44px 1fr 44px; align-items: center; }
  .osd nav { display: none; }
  .brand { --rail: var(--mrail); }
  :root { --mark: var(--mrail); }
  .osd { padding-right: calc(var(--edge-ink) - 8px); }
  .osd { justify-content: flex-end; }
  .stage .channel { padding-top: calc(var(--mrail) * 4.3 + 56px); }
  /* off Home the folded mark is short, so content starts higher; anything scrolled up fades out before it reaches the mark */
  /* (on a very short screen the mark gets small, and the fade stays below the burger instead) */
  .stage .channel:not(#home) { padding-top: max(calc(var(--mrail) * 2.6 + 34px), 94px); padding-bottom: 64px;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent max(calc(var(--mrail) * 2.6 + 6px), 66px), #000 max(calc(var(--mrail) * 2.6 + 30px), 90px));
    mask-image: linear-gradient(to bottom, transparent 0, transparent max(calc(var(--mrail) * 2.6 + 6px), 66px), #000 max(calc(var(--mrail) * 2.6 + 30px), 90px)); }
  /* Home only scrolls on a very short screen (zoomed right in); then it too fades out before reaching the mark */
  .stage .channel#home.scrolls {
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent calc(var(--mrail) * 4.3 + 26px), #000 calc(var(--mrail) * 4.3 + 50px));
    mask-image: linear-gradient(to bottom, transparent 0, transparent calc(var(--mrail) * 4.3 + 26px), #000 calc(var(--mrail) * 4.3 + 50px)); }
  /* Work fits one phone screen: a tighter card, and the line-up becomes a strip of small listings */
  #work .inner { gap: 0; }
  .listings { gap: 20px; }
  .case { gap: 13px; }
  #work h2 { font-size: 34px; }
  #work .lede { font-size: 15px; line-height: 1.5; }
  .credits dd { font-size: 13px; }
  .credits div { padding: 9px 8px 0 0; } .credits div + div { padding-left: 9px; }
  .credits dt { font-size: 12px; }
  .plot { height: 54px; }
  .trace figcaption span:last-child { display: none; }
  .log { gap: 8px; }
  .log li > span:last-child { font-size: 14px; }
  .lineup { display: flex; overflow-x: auto; scrollbar-width: none; border-top: 3px solid var(--phosphor); }
  .lu-head { display: none; }
  /* each small listing: number and title centred on one line; the strip fills the width when there's room */
  .row { flex: 1 0 auto; grid-template-columns: auto auto; justify-content: center; column-gap: 8px; align-items: center; padding: 12px 12px 8px; border-bottom: 0; border-right: 1px solid var(--line); } /* the font sits high in its line box, so 2px more on top centres the ink */
  .row:last-child { border-right: 0; }
  .row .n { grid-row: auto; font-size: 24px; line-height: 1; }
  .row .t { font-size: 14px; line-height: 1; white-space: nowrap; }
  .row .s { display: none; }
  .fp-sheet { width: 100vw; }
  /* about fits a phone: tighter bio and log, the crawl just above the hint */
  .about-inner { gap: 20px; }
  .about-copy { gap: 14px; }
  #about .lede { font-size: 15px; line-height: 1.5; }

  .learn { gap: 10px; padding-top: 0; }
  .lg li { grid-template-columns: 52px minmax(0, 1fr); padding: 9px 0; }
  .lg-t { font-size: 14px; gap: 4px; }
  .lg-t small { font-size: 12px; }
  .crawl { bottom: 50px; height: 34px; }
  .about-inner { grid-template-columns: 1fr; }
  .stage .channel#about { padding-bottom: 100px; }
  .crawl-track span { font-size: 13px; padding: 0 16px; }
  .crawl-track span::after { margin-left: 32px; }
  /* questions fit one phone screen while closed: tighter rows, smaller type */
  /* one rhythm down the page: the same 16px between every block, from the label to the steps */
  #playbook .inner, .pb-inner { gap: 16px; }
  .pb-side, .pb-pane { gap: 16px; }
  #playbook h2 { font-size: 30px; }
  #playbook .lede { font-size: 15px; line-height: 1.5; }
  .tabs { display: flex; overflow-x: auto; scrollbar-width: none; margin-top: 0; }
  .post { padding: 14px 0 16px; }
  .tab { flex: 1 0 auto; justify-content: center; padding: 11px 10px; font-size: 14px; border-bottom: 0; }
  .tab .tn { display: none; }
  .steps li:last-child { padding-bottom: 0; }
  .steps { --when: 76px; --gap: 12px; }
  .steps li { padding: 8px 0; }
  .steps .sn { font-size: 13px; }
  .steps h3 { font-size: 16px; }
  .steps p { font-size: 14px; }
  .post-x { font-size: 15px; }
  .pb-pane .btn { padding: 12px 18px; font-size: 14px; }
  .fp-reach { order: 1; }
  .note-body p, .note-body li { font-size: 16px; }
  .q { grid-template-columns: 30px minmax(0, 1fr) 14px; gap: 10px; padding: 12px 0; }
  .q .qt { font-size: 15px; }
  .a p { font-size: 14px; padding-bottom: 14px; }
  .fp-body { padding: 96px var(--gr) 48px var(--gl); }
  .fp-foot { padding: 0 var(--gr) calc(20px + env(safe-area-inset-bottom, 0px)) var(--gl); }
  .fp-body h2 { font-size: 46px; }
  .burger { display: block; grid-column: 3; }
  .hero-h { font-size: min(40px, 8.6vw); } /* sized so "static into signal." stays on one line */
  .tb-ring { width: 62px; height: 62px; }
  .tube .lines { opacity: .22; } /* on a small, close screen the lines are only a hint */
  .channel { padding: 120px var(--gr) 80px var(--gl); }
  .log li { grid-template-columns: 80px 1fr; gap: 10px; }
  .trace figcaption { display: grid; gap: 4px; } .trace figcaption span:last-child { text-align: left; }
}

.cursor { position: fixed; left: 0; top: 0; z-index: 80; pointer-events: none; opacity: 0; transition: opacity .3s; }
.cursor.on { opacity: 1; }
.cursor i {
  display: block; width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%;
  border: 1.5px solid var(--phosphor); box-shadow: 0 0 8px rgba(var(--glow), 0.5);
  transition: transform .55s var(--ease), background-color .4s ease, border-color .4s ease;
}
.cursor.hot i { transform: scale(2.4); background: var(--phosphor); border-color: var(--phosphor); }
.cursor.hot { mix-blend-mode: difference; }
/* over a typing field the ring narrows into a slim upright bar with small caps top and bottom, so it's clear you can type */
.cursor.text i { width: 2px; height: 18px; margin: -9px 0 0 -1px; border: 0; border-radius: 1px; background: var(--phosphor); box-shadow: 0 0 8px rgba(var(--glow), .6); transform: none; }
.cursor.text i::before, .cursor.text i::after { content: ""; position: absolute; left: -3px; width: 8px; height: 2px; border-radius: 1px; background: var(--phosphor); }
.cursor.text i::before { top: 0; } .cursor.text i::after { bottom: 0; }
.cursor i { position: relative; }
.cursor.down i { transform: scale(0.7); }

@media (prefers-reduced-motion: reduce) {
  .static, .tube .grain, .tube .hum, .rec, .sig-line path, .case.cut-out, .case.rise > *, .burst.on, .tune, .leave, .crawl-track { animation: none !important; }
  .cursor i, .brand b, .tb-ring, .guide, .g-list a, .g-foot { transition: none !important; }
}
/* the cold open: before the site comes on, a dark screen shows one SEO fact (a different one each visit, picked by the
   script) low on the left, with a thin bar along the bottom that fills as the page gets ready. Then the fact breaks up
   and the screen switches off like an old set: it folds to a bright line across the middle, the line shrinks to a
   point, and the site is there behind it. The scanlines and grain of the tube stay on top throughout. If the script
   never runs it never shows, and if it stalls the screen lifts by itself after 9s */
.intro { position: fixed; inset: 0; z-index: 49; background: var(--screen); pointer-events: none; transform-origin: 50% 50%;
  animation: introsafe .4s ease 9s forwards; }
@keyframes introsafe { to { opacity: 0; visibility: hidden; } }
.in-card { position: absolute; left: var(--gl); right: var(--gr); bottom: clamp(70px, 19vh, 190px); display: grid; gap: clamp(14px, 2.2vh, 22px); opacity: 0; }
.in-card.on { opacity: 1; }
.in-card.on > * { animation: tunein .8s var(--ease) both; }
.in-card.on > :nth-child(2) { animation-delay: .12s; }
.in-card.on > :nth-child(3) { animation-delay: .3s; }
.in-kick { margin: 0; display: flex; align-items: center; font: 700 14px/1 var(--title); font-stretch: 62%; letter-spacing: .2em; text-transform: uppercase; color: var(--dim); }
.in-kick .rec { width: 8px; height: 8px; }
.in-kick b { font-weight: 700; color: var(--phosphor); margin-right: .6em; }
.in-fact { margin: 0; max-width: 17ch; font: 800 clamp(26px, min(4.2vw, 7vh), 64px)/1.02 var(--title); font-stretch: 125%; letter-spacing: -.035em; color: var(--phosphor);
  text-wrap: balance; text-shadow: 0 0 22px rgba(var(--glow), .18); }
.in-fact em { font-style: normal; color: var(--live); text-shadow: 0 0 18px rgba(var(--live-rgb), .45); }
.in-src { margin: 0; font: 500 11px/1.4 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--dim); }
/* the bar: a hairline across the bottom, lit as far as the page has loaded, with the count beside it */
.in-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: rgba(var(--glow), .1); }
.in-bar i { position: absolute; inset: 0; background: var(--phosphor); box-shadow: 0 0 10px rgba(var(--glow), .6); transform: scaleX(0); transform-origin: 0 50%; }
.in-pc { position: absolute; right: var(--gr); bottom: 14px; font: 500 11px/1 var(--mono); letter-spacing: .16em; color: var(--dim); font-variant-numeric: tabular-nums; }
/* going: the fact tunes out, the bar and count fade, then the screen folds away */
.intro.out .in-card > * { animation: rollout .3s ease-in both; }
.intro.out .in-bar, .intro.out .in-pc { opacity: 0; transition: opacity .25s ease; }
.intro.off { animation: crtoff .8s cubic-bezier(.7, 0, .2, 1) forwards; }
@keyframes crtoff {
  0%   { transform: scale(1, 1); background-color: var(--screen); }
  50%  { transform: scale(1, .004); background-color: var(--phosphor); box-shadow: 0 0 40px 6px rgba(var(--glow), .7); }
  78%  { transform: scale(.06, .004); background-color: var(--phosphor); box-shadow: 0 0 40px 6px rgba(var(--glow), .7); opacity: 1; }
  100% { transform: scale(0, .004); background-color: var(--phosphor); opacity: 0; }
}
@keyframes fadeout { to { opacity: 0; } }
.lite .intro.off { animation: fadeout .3s ease forwards; }
@media (prefers-reduced-motion: reduce) { .intro.off { animation: fadeout .3s ease forwards; } .in-card.on > * { animation: none; } }

/* between pages: the old page goes dark behind the snow and stays dark while the next loads; the next stays dark until it tunes in */
body.leaving .stage { opacity: 0; transition: opacity .12s ease .1s; }
html.arriving .stage { opacity: 0; animation: arrive-safe 0s linear 1.5s forwards; } /* (shown anyway if the script never runs) */
@keyframes arrive-safe { to { opacity: 1; } }
