/* Room photo + TV rectangle (fractions of the photo): lines from tools/room.py.
   Lockup geometry: line from tools/canva_lockup.py. */
:root { --tv-radius: 7% / 9%; --red: #E93A2C;
        --lockup-ar: 456.48 / 600.81; --frame-x: 0.1595; --frame-y: 0.2173; --frame-w: 0.7286; --frame-h: 0.5546; --brush-ar: 440.48 / 141.51; }
:root { --room-ar: 5504 / 3072; --tv-x: 0.4398; --tv-y: 0.4173; --tv-w: 0.1103; --tv-h: 0.1460; }
@media (orientation: portrait) { :root { --room-ar: 1728 / 3072; --tv-x: 0.3245; --tv-y: 0.4173; --tv-w: 0.3513; --tv-h: 0.1460; } }

html { background: #000; color: #fff; font-family: system-ui, sans-serif; -webkit-text-size-adjust: 100%; }
body { margin: 0; }

/* Scroll distance only. */
.track { height: 600svh; }   /* five screens of scroll; beats.js paces the story over it */

/* The room never moves. The clip box is anchored at the top with the large
   viewport height, so a collapsing toolbar only uncovers more of the bottom. */
.stage-clip { position: fixed; z-index: 0; top: 0; left: 0; width: 100%; height: 100lvh; overflow: hidden; overflow: clip; }
.stage {
  position: absolute; left: 50%; top: 50%;
  width: max(100vw, 100lvh * var(--room-ar));
  aspect-ratio: var(--room-ar);
  translate: -50% -50%;
  transform-origin: calc((var(--tv-x) + var(--tv-w) / 2) * 100%) calc((var(--tv-y) + var(--tv-h) / 2) * 100%);
}
.room img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Same rectangle on the stage and inside the phone's camera view. */
.tv, .vf-tv {
  position: absolute; overflow: hidden; overflow: clip; display: grid; place-items: center;
  left: calc(var(--tv-x) * 100%); top: calc(var(--tv-y) * 100%);
  width: calc(var(--tv-w) * 100%); height: calc(var(--tv-h) * 100%);
  border-radius: var(--tv-radius);
}
.lockup { position: relative; height: 82%; aspect-ratio: var(--lockup-ar); }
.lockup img { position: absolute; inset: 0; width: 100%; height: 100%; }
.tv-glow { position: absolute; inset: 0; pointer-events: none; }

.bar { position: fixed; z-index: 3; top: 0; left: 0; right: 0; display: flex; justify-content: space-between; align-items: center;
       padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left)); }
.ui { position: fixed; z-index: 2; inset: 0; pointer-events: none; }
.side, .phone { pointer-events: auto; }
.side { animation: fade-in 0.6s var(--ease-out) 0.2s backwards; } /* also hides the TR→EN swap */

.visually-hidden, .hp { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
@keyframes fade-in { from { opacity: 0; } }

/* TV glow and light spill: they come on with the show (beats.js) */
.tv-glow { background: radial-gradient(ellipse at 50% 45%, rgb(150 210 255 / 0.18), transparent 70%); animation: flicker 7s infinite; }
/* Light spill on the room: a box around the TV only, normal blending. */
.spill {
  position: absolute; pointer-events: none;
  left: calc((var(--tv-x) - var(--tv-w)) * 100%); top: calc((var(--tv-y) - var(--tv-h)) * 100%);
  width: calc(var(--tv-w) * 300%); height: calc(var(--tv-h) * 300%);
  background: radial-gradient(closest-side, rgb(140 190 255 / 0.12), transparent);
  animation: flicker 7s infinite;
}
/* Mostly steady, two short dips per loop. */
@keyframes flicker { 0%, 28%, 32%, 62%, 66%, 100% { opacity: 1; } 30% { opacity: 0.85; } 64% { opacity: 0.92; } }

@media (prefers-reduced-motion: reduce) { .tv-glow, .spill { animation: none; } }

/* Phone and screens */
.phone {
  position: fixed; z-index: 2; aspect-ratio: 899 / 1806;
  left: 50%; bottom: 4svh; height: var(--phone-h);   /* fully visible under the caption, centered on the TV */
  translate: -50% calc(-1 * var(--kb, 0px));   /* centered; lifted above the keyboard */
  border-radius: 15% / 7.4%;
  transform: translateY(110%);              /* start state; Motion takes over */
}
.phone-screen { position: absolute; inset: 2.1% 5% 1.77% 5.12%; border-radius: 12.4% / 5.8%; overflow: hidden; overflow: clip; background: #000; container-type: size; }
.phone-frame { position: absolute; z-index: 4; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.screens { position: absolute; inset: 0; --pt: calc(100cqw / 393); }   /* iPhone points on a 393pt screen */
/* Screens stack: camera view, then the app (launches over it), then the sign-up (rises as a sheet). */
.screen { position: absolute; inset: 0; box-sizing: border-box; display: flex; flex-direction: column; isolation: isolate; } /* layers stay inside their screen */
.screen-app { transform-origin: 50% calc(585 * var(--pt)); pointer-events: none; }   /* the tiviqr.com chip's middle: the app grows from it */
.screen-join { transform: translateY(100cqh); background: #1C1C1E; }
.viewfinder { position: absolute; inset: 0; overflow: hidden; overflow: clip; } /* hidden: iOS 15 fallback */
.vf-zoom { position: absolute; inset: 0; }
.tv-show { position: absolute; inset: 0; display: grid; place-items: center; }
.tv-show { opacity: 0; }
.tv-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vf-mirror { background: url("assets/show-poster.webp") center / cover; } /* until the first frame, and with reduced motion */
.tv-bug.lockup { position: absolute; right: 4%; bottom: 6%; height: 22%; } /* a small corner bug, bottom right; the camera zoom (beats.js) finds it */
/* Its own layer: Safari draws the playing video on a layer that would cover the bug otherwise. */
.tv-show .tv-bug { will-change: transform; }
/* In the camera view the bug is drawn at the camera's full zoom (5.6, beats.js) and shrunk back on its own layer,
   so Safari rasterizes it big and the zoom shows it sharp instead of stretching a 30px bitmap. */
.vf-tv .tv-bug img { width: 560%; height: 560%; transform: scale(0.17857); transform-origin: 0 0; will-change: transform; }
/* The camera's copy of the room: story.js places it where the real room is behind the risen phone (left, top and
   width in px), so the camera shows exactly what the phone covers. */
.viewfinder-room { position: absolute; aspect-ratio: var(--room-ar); background: var(--room) center / cover; }
/* Where the camera aims: the red frame's box (invisible). */
.scan-aim { position: absolute; left: calc(var(--frame-x) * 100%); top: calc(var(--frame-y) * 100%);
            width: calc(var(--frame-w) * 100%); height: calc(var(--frame-h) * 100%); }
[data-beat="spill"], [data-beat="teaser1"], [data-beat="subline"], [data-beat="teaser2"], [data-beat="teaser3"], [data-beat="teaser4"], [data-beat="soon"], [data-beat="lock-label"], [data-beat="qr-lock"],
[data-beat="app-modal"], [data-beat$="-green"], [data-beat="knob-check"], [data-beat="sheet-status"], [data-beat="legal"],
[data-beat="app"] { opacity: 0; }   /* start states; Motion takes over */

/* Portrait: size the phone by width so the form fits; it may run off the bottom edge. */
@media (orientation: portrait) {
  .phone { right: auto; bottom: auto; left: 50%; top: 26svh; height: auto; width: min(88vw, max(420px, 64vw));   /* tablets: the TV grows with the width (cabinet about 57vw, a little right of center), so the phone does too, to keep the cabinet hidden */
           translate: -50% calc(-1 * var(--kb, 0px)); }
}

/* Invisible things don't take taps. */
.soon, .screen-join { pointer-events: none; }
.is-end .soon, .is-join .screen-join, .no-story .soon, .no-story .screen-join { pointer-events: auto; }

@media (prefers-reduced-motion: reduce) {
  .phone { transform: none; opacity: 0; }
  .screen-join { transform: none; opacity: 0; }
}
/* No Motion (failed to load or threw): skip the story and show the sign-up. */
.no-story .phone { transform: none; opacity: 1; }
.no-story .screen-join { transform: none; opacity: 1; }
.no-story [data-beat="soon"], .no-story [data-beat="legal"] { opacity: 1; }
.no-story [data-beat="headline"], .no-story [data-beat="hint"] { opacity: 0; }

/* Slide to join */
.slide { position: relative; width: 100%; height: 52px; border: 0; border-radius: 26px; background: var(--field); color: #ccc; font: inherit;
         user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; }
.slide:disabled { opacity: 0.6; }
.slide-knob { position: absolute; z-index: 2; left: 4px; top: 4px; width: 44px; height: 44px; border-radius: 50%; background: var(--red);
              color: #fff; display: grid; place-items: center; touch-action: none; cursor: grab;
              }
.slide-knob.dragging { cursor: grabbing; }
#email { font-size: 16px; } /* 16px+ keeps iOS from zooming the page */
.join-form[aria-busy="true"] .slide { opacity: 0.6; pointer-events: none; }

/* ───────────── Visual layer ───────────── */

@font-face { font-family: 'Comfortaa'; src: url('assets/fonts/comfortaa-700-tr.woff2') format('woff2'); font-weight: 700; font-display: swap; }
@font-face { font-family: 'Noto Sans'; src: url('assets/fonts/noto-sans-400-tr.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Noto Sans'; src: url('assets/fonts/noto-sans-600-tr.woff2') format('woff2'); font-weight: 600; font-display: swap; }

:root {
  --display: 'Comfortaa', 'Avenir Next', system-ui, sans-serif;
  --body: 'Noto Sans', system-ui, sans-serif;
  --ink: #fff;
  --ink-2: rgb(255 255 255 / 0.78);
  --ink-3: rgb(255 255 255 / 0.6);
  --field: #2C2C2E;            /* iOS dark fill, reads on the #1C1C1E sheet */
  --edge: clamp(20px, 5.5vw, 88px);
  --phone-h: 70svh;   /* wide screens (no cap: on big monitors a capped phone got narrower than the TV); portrait phones size the phone by width */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --red-fill: #DC2626;          /* the app's button red: white text reads at 4.8:1 */
  /* Type roles (owner: one system for the headlines). Comfortaa: statement (the opening line, the punchline,
     "Yakında.") and caption (the step captions). Noto Sans: ui (copy and controls) and small (fine print, labels).
     Phones and short sideways screens retune the sizes below; the roles stay. */
  --type-xl: clamp(2.6rem, min(5.4vw, 9svh), 5.6rem);   /* 9svh: on short, wide windows (laptops) the statement minds the height too */
  --type-m: clamp(1.7rem, 3vw, 2.9rem);
  --type-ui: 0.9rem;
  --type-small: 0.78rem;
}

html { font-family: var(--body); scrollbar-width: thin; scrollbar-color: rgb(255 255 255 / 0.25) transparent; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
::selection { background: var(--red); color: #fff; }
:focus-visible { outline: 2px solid #fff; outline-offset: 3px; } /* the outline follows each control's own corners */
a { color: inherit; text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
a, button { -webkit-tap-highlight-color: transparent; }  /* no gray tap flash on phones */
.track { position: relative; }
.track-end { position: absolute; bottom: 0; left: 0; width: 1px; height: 1px; }
/* A scroll travels to the next stop (beats.js STOPS, markers from story.js) and can't skip one. */
html:has(.stop) { scroll-snap-type: y mandatory; }
.stop { position: absolute; left: 0; width: 1px; height: 1px; scroll-snap-align: start; scroll-snap-stop: always; }

/* Shadow that keeps the text readable on the photo */
.ui::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgb(8 4 2 / 0.8) 0%, rgb(8 4 2 / 0.62) 18%, rgb(8 4 2 / 0.25) 32%, transparent 44%, transparent 78%, rgb(8 4 2 / 0.55) 100%); /* the text band at the top, and the fine print */
}

/* Bar */
.bar { gap: 12px; padding-left: var(--edge); padding-right: var(--edge); padding-top: max(18px, env(safe-area-inset-top)); }
.bar-logo { height: 30px; width: auto; display: block; margin-right: auto; }
.bar-join {
  font: 600 var(--type-ui)/1 var(--body); text-decoration: none; color: #fff; background: var(--red-fill);
  padding: 0.7em 1.1em; border-radius: 999px; white-space: nowrap;
  box-shadow: 0 6px 16px -6px rgb(0 0 0 / 0.6);
  transition: transform 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out);
}
.lang { display: flex; padding: 3px; border-radius: 999px; background: rgb(0 0 0 / 0.45); border: 1px solid rgb(255 255 255 / 0.14); }
.lang button {
  font: 600 var(--type-small)/1 var(--body); letter-spacing: 0.04em; color: var(--ink-3); background: none; border: 0;
  padding: 0.55em 0.75em; border-radius: 999px; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: transform 0.16s var(--ease-out);
}
.lang button[aria-pressed="true"] { color: #000; background: #fff; }
@media (hover: hover) and (pointer: fine) {
  .bar-join:hover { transform: translateY(-1px); box-shadow: 0 10px 22px -8px rgb(0 0 0 / 0.75); }
  .lang button:hover:not([aria-pressed="true"]) { color: #fff; }
  .slide:not(:disabled):hover .slide-knob { translate: 3px 0; }
}
/* Press feedback, since the tap flash is off (after :hover so it wins while pressed) */
.bar-join:active, .lang button:active { transform: scale(0.97); }
a:active { opacity: 0.7; }

/* Text: one centered slot between the bar and the phone's top edge; headline, captions and "Coming soon" take
   turns in it (owner: everything centered, text over the TV). */
.side {
  --band-top: calc(max(18px, env(safe-area-inset-top)) + 52px);
  --band-bottom: calc(96svh - var(--phone-h) - 8px);
  position: absolute; left: var(--edge); right: var(--edge); top: var(--band-top); height: calc(var(--band-bottom) - var(--band-top));
  display: grid; grid-template-rows: minmax(0, 1fr); align-items: center; justify-items: center; text-align: center;   /* the row stays the band: a tall headline overflows it instead of moving the captions */
}
.intro { align-self: start; max-width: min(100%, 1000px); margin-top: clamp(2svh, (100svh - 600px) * 0.4, 8svh); }   /* about midway between the bar and the TV; closer to the bar on short windows, so the scroll cue clears the TV */
.teasers, .soon { width: min(100%, 860px); }
.side > * { grid-area: 1 / 1; }
/* Comfortaa stops at 700: a same-color outline behind the letters makes it heavier, on every display line alike
   (owner: all heavy). Each sets it at its own size (an inherited outline would keep its parent's thickness). */
.headline, .teaser, .subline, .soon-title, .done-title, .doc-main h1 { -webkit-text-stroke: 0.04em currentColor; paint-order: stroke fill; }
.headline {
  font: 700 var(--type-xl)/1.1 var(--display); letter-spacing: -0.025em; margin: 0;   /* 1.1: at 0.98 the tail of y touched the t below */
  text-wrap: balance; text-shadow: 0 2px 30px rgb(0 0 0 / 0.55);
}
.hint {
  display: inline-flex; align-items: center; gap: 0.5em; margin: 1.6rem 0 0;
  font: 600 var(--type-small)/1 var(--body); letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-2);
}
.hint-icon { width: 18px; height: 18px; animation: nudge 1.8s ease-in-out infinite; }
@keyframes nudge { 0%, 100% { transform: translateY(-2px); } 50% { transform: translateY(4px); } }
.teasers { display: grid; }
.teaser { grid-area: 1 / 1; align-self: start; }   /* the captions take turns in one spot; each box hugs its text (the subline hangs under it) */
.teaser {
  margin: 0; font: 700 var(--type-m)/1.2 var(--display); letter-spacing: -0.02em;   /* 1.08 let the tails of y/ş nearly touch k/t/l on the next line */
  text-wrap: balance; text-shadow: 0 2px 24px rgb(0 0 0 / 0.6); position: relative;
}
/* The punchline (owner: bigger, filling the space): the caption's own font, larger. It hangs under the caption, so
   the captions that share the spot don't move. */
.subline { position: absolute; top: 100%; left: 0; right: 0; margin-top: 0.6em; font-size: var(--type-xl); line-height: 1.1; letter-spacing: -0.025em; text-wrap: balance; }   /* the statement size, like the opening line */
.soon-title { margin: 0 0 0.6rem; font: 700 var(--type-xl)/1.1 var(--display); letter-spacing: -0.025em; }
.contact { margin: 0 auto 0.6rem; font-size: var(--type-ui); line-height: 1.5; color: var(--ink-2); max-width: 60ch; }
.contact a { color: #fff; font-weight: 600; }
.noscript { position: fixed; top: calc(max(18px, env(safe-area-inset-top)) + 60px); left: var(--edge); right: var(--edge); margin: 0;
            font: 600 1rem/1.5 var(--body); color: var(--ink-2); } /* in the empty band under the bar, not over the headline */

/* Phone frame */
.phone { box-shadow: 0 50px 90px -24px rgb(0 0 0 / 0.85), 0 14px 30px -12px rgb(0 0 0 / 0.6); }
.screen { padding: 19cqh 8cqw 8cqh; gap: 0; }

/* Viewfinder */
/* The iOS Camera app, drawn from scratch (owner: like the real one; no Apple artwork or symbols): black bars top
   and bottom, the picture in the 4:3 window between them (125-650pt) with a 3x3 grid; yellow brackets and the
   tiviqr.com chip when the QR is found. iPhone points, measured from the owner's iPhone screenshot. */
.cam { position: absolute; inset: 0; z-index: 2; pointer-events: none; color: #fff; --cam-yellow: #FFD60A;
       font-family: -apple-system, BlinkMacSystemFont, system-ui, sans-serif; }
.cam svg { overflow: visible; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.cam .cam-fill { fill: currentColor; stroke: none; }
.cam text { stroke: none; fill: #fff; font: 700 6.4px/1 -apple-system, BlinkMacSystemFont, system-ui, sans-serif; }
.cam .cam-badge { fill: #fff; stroke: none; }
.cam .cam-badge + text { fill: #000; }
.cam-top { position: absolute; inset: 0 0 auto; height: calc(125 * var(--pt)); box-sizing: border-box; padding-top: calc(46 * var(--pt));
           background: #000; display: flex; justify-content: center; align-items: center; gap: calc(22 * var(--pt)); }
.cam-i { width: calc(23 * var(--pt)); height: calc(23 * var(--pt)); }
.cam-ev { display: grid; justify-items: center; color: var(--cam-yellow); font-size: calc(15 * var(--pt)); font-weight: 500; line-height: 1; }
.cam-ev small { font-size: calc(9 * var(--pt)); font-weight: 600; margin-top: calc(2 * var(--pt)); }
.cam-grid { position: absolute; left: 0; right: 0; top: calc(125 * var(--pt)); height: calc(525 * var(--pt)); }
.cam-grid::before, .cam-grid::after { content: ""; position: absolute; border: 0 solid rgb(255 255 255 / 0.35); }
.cam-grid::before { inset: 0 33.333%; border-inline-width: 1px; }
.cam-grid::after { inset: 33.333% 0; border-block-width: 1px; }
/* Sized by story.js (--qr) to the QR in the close-up, which the zoom puts at (50%, 46%). */
.cam-brackets { position: absolute; left: 50%; top: 46%; translate: -50% -50%; width: calc(var(--qr, 0.3) * 100cqw); height: auto; aspect-ratio: 1; }
.cam .cam-brackets path { stroke: var(--cam-yellow); stroke-width: calc(3 * var(--pt)); vector-effect: non-scaling-stroke; }
.cam-found { position: absolute; left: 0; right: 0; top: calc(570 * var(--pt)); height: calc(30 * var(--pt)); }   /* 598pt in the real app; lifted clear of Safari's bottom bar on phones (beats.js grows the app from here) */
.cam-chip { position: absolute; left: 50%; top: 0; translate: -50% 0; height: 100%; margin: 0; box-sizing: border-box;
            display: inline-flex; align-items: center; gap: calc(6 * var(--pt)); padding: 0 calc(11 * var(--pt)) 0 calc(9 * var(--pt));
            border-radius: 999px; background: var(--cam-yellow); color: #000; font-size: calc(15 * var(--pt)); font-weight: 500; white-space: nowrap; }
.cam-chip svg { width: calc(16 * var(--pt)); height: calc(16 * var(--pt)); stroke-width: 1.8; }
.cam .cam-x { width: calc(12 * var(--pt)); height: calc(12 * var(--pt)); margin-left: calc(4 * var(--pt)); stroke-width: 2.4; }
.cam-scan { position: absolute; left: calc(339 * var(--pt)); top: calc(-4 * var(--pt)); width: calc(38 * var(--pt)); height: calc(38 * var(--pt));
            border-radius: calc(11 * var(--pt)); background: rgb(58 58 60 / 0.75); display: grid; place-items: center; }
.cam-scan svg { width: calc(21 * var(--pt)); height: calc(21 * var(--pt)); }
.cam-bottom { position: absolute; inset: calc(650 * var(--pt)) 0 0; background: #000; }
.cam-bottom > * { position: absolute; translate: -50% -50%; }
.cam-bottom > :nth-child(1) { left: calc(56 * var(--pt)); top: calc(54 * var(--pt)); }
.cam-bottom > :nth-child(2) { left: calc(196.5 * var(--pt)); top: calc(54 * var(--pt)); }
.cam-bottom > :nth-child(3) { left: calc(336 * var(--pt)); top: calc(54 * var(--pt)); }
.cam-bottom > :nth-child(4) { left: calc(56 * var(--pt)); top: calc(148 * var(--pt)); }
.cam-bottom > :nth-child(5) { left: calc(196.5 * var(--pt)); top: calc(148 * var(--pt)); }
.cam-bottom > :nth-child(6) { left: calc(336 * var(--pt)); top: calc(148 * var(--pt)); }
.cam-btn { width: calc(47 * var(--pt)); height: calc(47 * var(--pt)); border-radius: 50%; background: rgb(44 44 46); display: grid; place-items: center; }
.cam-btn svg { width: calc(24 * var(--pt)); height: calc(24 * var(--pt)); stroke-width: 1.8; }
.cam-f { font-size: calc(23 * var(--pt)); font-style: italic; line-height: 1; }
.cam-shutter { width: calc(74 * var(--pt)); height: calc(74 * var(--pt)); border-radius: 50%; border: calc(4 * var(--pt)) solid #fff; box-sizing: border-box;
               display: grid; place-items: center; }
.cam-shutter::after { content: ""; width: calc(60 * var(--pt)); height: calc(60 * var(--pt)); border-radius: 50%; background: #fff; }
.cam-thumb { width: calc(46 * var(--pt)); height: calc(46 * var(--pt)); border-radius: 50%; box-sizing: border-box; border: 1px solid rgb(255 255 255 / 0.25);
             background: var(--room) 50% 47% / 700% auto, #222; }
.cam-modes { width: calc(214 * var(--pt)); height: calc(47 * var(--pt)); border-radius: 999px; background: rgb(28 28 30); overflow: hidden;
             display: flex; align-items: center; justify-content: center; gap: calc(14 * var(--pt));
             font-size: calc(14.5 * var(--pt)); font-weight: 500; letter-spacing: 0.02em; white-space: nowrap; }
.cam-modes .is-on { color: var(--cam-yellow); background: rgb(58 58 60); border-radius: 999px; padding: calc(9 * var(--pt)) calc(16 * var(--pt)); }

/* The tiviqr app, rebuilt from its SwiftUI code (TiviQR: LSHeaderView, LSTileView, CheckInModal,
   FloatingTabBar) with made-up shows. Sizes are iPhone points on a 393pt-wide screen; system font; the app's colors. */
.screen-app { padding: 0; }
.app { position: absolute; inset: 0; overflow: hidden; background: #000; color: #fff;
       font-family: -apple-system, BlinkMacSystemFont, system-ui, sans-serif; -webkit-font-smoothing: antialiased; }
.app p, .app ul { margin: 0; padding: 0; }
.app-icons { position: absolute; }
.app .i { width: calc(24 * var(--pt)); height: calc(24 * var(--pt)); fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.app-status { position: absolute; inset: 0 0 auto; height: calc(54 * var(--pt)); color: #fff; font-family: -apple-system, BlinkMacSystemFont, system-ui, sans-serif; }
.app-time { position: absolute; left: calc(51 * var(--pt)); top: calc(21 * var(--pt)); font-size: calc(17 * var(--pt)); font-weight: 600; line-height: 1; }
.app-sys { position: absolute; right: calc(35 * var(--pt)); top: calc(23 * var(--pt)); display: flex; align-items: center; gap: calc(6 * var(--pt)); }
.app-sys svg { fill: #fff; height: calc(12 * var(--pt)); }
.sys-signal { width: calc(18 * var(--pt)); }
.sys-wifi { width: calc(16 * var(--pt)); }
.app-status .sys-battery { width: calc(27 * var(--pt)); height: calc(13 * var(--pt)); }
.bat-shell { fill: none; stroke: rgb(255 255 255 / 0.45); }
.app-header { position: absolute; top: calc(60 * var(--pt)); left: 0; right: 0; height: calc(42 * var(--pt)); }
.app-logo { position: absolute; left: calc(25.7 * var(--pt)); top: calc(4.8 * var(--pt)); height: calc(32.4 * var(--pt)); width: auto; }
.app-actions { position: absolute; right: calc(16 * var(--pt)); top: calc(21 * var(--pt)); translate: 0 -50%; display: flex; align-items: center; gap: calc(16 * var(--pt)); color: #DC2626; }
.app .i-bell { width: calc(22 * var(--pt)); height: calc(22 * var(--pt)); }
.app-tiles { position: absolute; top: calc(102 * var(--pt)); left: calc(16 * var(--pt)); display: flex; gap: calc(12 * var(--pt)); list-style: none; }
.app-tiles li { position: relative; width: calc(85 * var(--pt)); padding-top: calc(10 * var(--pt)); display: flex; flex-direction: column; align-items: center; }
.app-tiles img { width: calc(78 * var(--pt)); height: calc(78 * var(--pt)); border-radius: calc(6 * var(--pt)); object-fit: cover; background: #1C1C1E; }
.app-tiles span { margin-top: calc(8 * var(--pt)); width: 100%; font-size: calc(11 * var(--pt)); font-weight: 500; line-height: 1.2;
                  text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Live show: a 3pt system-red ring 2pt off the image, pulsing like the app's (1.5s, 1 <-> 0.3). */
.app-tiles .is-live::before { content: ""; position: absolute; top: calc(5 * var(--pt)); left: calc(-1.5 * var(--pt));
  width: calc(88 * var(--pt)); height: calc(88 * var(--pt)); box-sizing: border-box; border: calc(3 * var(--pt)) solid #FF453A;
  border-radius: calc(9.5 * var(--pt)); animation: live-pulse 1.5s ease-in-out infinite alternate; }
@keyframes live-pulse { to { opacity: 0.3; } }
.app-feed { position: absolute; top: calc(228 * var(--pt)); left: 0; right: 0; }
.feed-head { display: flex; align-items: center; gap: calc(12 * var(--pt)); padding: calc(2 * var(--pt)) calc(16 * var(--pt)); }
.feed-head img { width: calc(50 * var(--pt)); height: calc(50 * var(--pt)); border-radius: calc(6 * var(--pt)); object-fit: cover; background: #1C1C1E; }
.feed-head b { display: block; color: #FF453A; font-size: calc(17 * var(--pt)); }
.feed-head small { display: block; color: #8E8E93; font-size: calc(12 * var(--pt)); }
.feed-media { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; margin-top: calc(8 * var(--pt)); background: #1C1C1E; }
.feed-caption { padding: calc(8 * var(--pt)) calc(16 * var(--pt)) 0; font-size: calc(16 * var(--pt)); line-height: 1.3; }
.feed-caption b { color: #FF453A; font-weight: 600; }
.feed-caption b.red { color: #DC2626; }
.i-heart { width: calc(17 * var(--pt)); height: calc(17 * var(--pt)); fill: #8E8E93; vertical-align: -0.15em; }
/* Check-in modal: 40% black over the app (not the tab bar), card centered in 24pt margins. */
.app-modal { position: absolute; inset: 0; }
.app-dim { position: absolute; inset: 0; background: rgb(0 0 0 / 0.4); }
.checkin { position: absolute; left: calc(24 * var(--pt)); right: calc(24 * var(--pt)); top: calc(229 * var(--pt)); border-radius: calc(20 * var(--pt)); overflow: hidden; }
.checkin-art { display: block; width: 100%; height: calc(200 * var(--pt)); object-fit: cover; background: #1C1C1E; }
.checkin-body { background: rgb(0 0 0 / 0.95); padding: calc(16 * var(--pt)) 0 calc(28 * var(--pt)); display: flex; flex-direction: column; align-items: center; gap: calc(16 * var(--pt)); }
.checkin-live { display: flex; align-items: center; gap: calc(6 * var(--pt)); color: #DC2626; font-size: calc(12 * var(--pt)); font-weight: 700; line-height: calc(16 * var(--pt)); }
.checkin-live i { width: calc(10 * var(--pt)); height: calc(10 * var(--pt)); border-radius: 50%; background: #DC2626; }
.checkin-title { font-size: calc(22 * var(--pt)); font-weight: 700; line-height: calc(28 * var(--pt)); padding: 0 calc(20 * var(--pt)); }
.checkin-welcome { font-size: calc(15 * var(--pt)); line-height: calc(20 * var(--pt)); color: #8E8E93; }
.checkin-slider { position: relative; width: calc(305 * var(--pt)); height: calc(60 * var(--pt)); margin-top: calc(8 * var(--pt));
                  border-radius: calc(30 * var(--pt)); background: rgb(142 142 147 / 0.3); overflow: hidden; }
/* Progress: a track-wide pill pushed left so only its end shows, trailing the knob (red, turning green). */
.checkin-fill { position: absolute; inset: 0; border-radius: inherit; background: linear-gradient(90deg, rgb(255 0 0 / 0.7), rgb(255 0 0 / 0.4)); transform: translateX(-62.341cqw); }
.fill-green { position: absolute; inset: 0; border-radius: inherit; background: linear-gradient(90deg, rgb(48 209 88 / 0.7), rgb(48 209 88 / 0.4)); }
.checkin-label { position: absolute; inset: 0; display: grid; place-items: center; font-size: calc(16 * var(--pt)); font-weight: 600; color: rgb(255 255 255 / 0.8); }
.checkin-knob { position: absolute; left: 0; top: 0; width: calc(60 * var(--pt)); height: calc(60 * var(--pt)); border-radius: 50%; background: #FF0000; display: grid; place-items: center; color: #fff; }
.knob-green { position: absolute; inset: 0; border-radius: 50%; background: #30D158; }
.app .checkin-knob .i { grid-area: 1 / 1; position: relative; width: calc(22 * var(--pt)); height: calc(22 * var(--pt)); stroke-width: 3; }
/* The knob takes the finger on the check-in card (story.js); a bigger invisible hit area around it. */
.is-checkin .checkin-knob { pointer-events: auto; touch-action: none; cursor: grab; }
.is-checkin .checkin-knob:active { cursor: grabbing; }
.checkin-knob::after { content: ''; position: absolute; inset: -10px; border-radius: 50%; }
.app-tabbar { position: absolute; left: calc(16 * var(--pt)); right: calc(16 * var(--pt)); bottom: calc(20 * var(--pt)); height: calc(64 * var(--pt));
              box-sizing: border-box; padding: 0 calc(8 * var(--pt)); border-radius: calc(28 * var(--pt)); display: flex; align-items: center;
              background: rgb(28 28 30 / 0.85); border: 1px solid rgb(255 255 255 / 0.1); box-shadow: 0 calc(8 * var(--pt)) calc(16 * var(--pt)) rgb(0 0 0 / 0.5); }
.app-tabbar span { position: relative; flex: 1; display: grid; place-items: center; height: calc(44 * var(--pt)); color: rgb(255 255 255 / 0.4); }
.app .app-tabbar .i { width: calc(20 * var(--pt)); height: calc(20 * var(--pt)); }
.app-tabbar .is-active { color: #fff; }
.app-tabbar .is-active::before { content: ""; position: absolute; inset: 0; margin: auto; width: calc(50.6 * var(--pt)); height: calc(50.6 * var(--pt)); border-radius: 50%;
  background: linear-gradient(135deg, #DC2626, #B41919); box-shadow: 0 calc(4.6 * var(--pt)) calc(6.9 * var(--pt)) rgb(220 38 38 / 0.35); }
.app .app-tabbar .is-active .i { position: relative; width: calc(23 * var(--pt)); height: calc(23 * var(--pt)); stroke-width: 2.1; }
@media (prefers-reduced-motion: reduce) { .app-tiles .is-live::before { animation: none; } }


/* Join */
/* Sign-up: an iOS full-screen sheet over the app (which shrinks back behind it, beats.js), with the
   phone's status bar on top. Icon, brush and line first, the show posters fanned in the middle, the form below, the fine print at the very bottom.
   The sheet ends where the visible screen does (--sheet-cut from main.js), so on portrait phones, where
   the phone runs off the bottom edge, the form and the fine print stay on screen. */
.screens .screen-join { top: 0; bottom: var(--sheet-cut, 0px); border-radius: calc(12 * var(--pt)) calc(12 * var(--pt)) 0 0;
  padding: calc(66 * var(--pt)) calc(26 * var(--pt)) calc(26 * var(--pt) + var(--sheet-foot, 0px)); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; }
.join-top { display: flex; flex-direction: column; align-items: center; text-align: center; }
.join-icon { width: calc(60 * var(--pt)); height: calc(60 * var(--pt)); }
.screen-join h2 { width: 100%; margin: calc(10 * var(--pt)) 0 calc(6 * var(--pt)); display: grid; place-items: center; }
.brush { display: block; width: 86%; aspect-ratio: var(--brush-ar); color: #fff; }
.join-fan { position: relative; flex: 1 1 calc(132 * var(--pt)); min-height: 0; container-type: size; }
/* The fan takes the room the form leaves (owner: a short phone's sheet looked empty): drawn on a 341 x 132pt box
   (the sheet's width less its padding), shrunk to fit when the box is shorter, gone when there's next to none
   (iPhone SE). --u is one of those points. Not var(--pt): its cqw would measure this box, not the screen. */
.join-fan img { --u: min(100cqw / 341, 100cqh / 132); position: absolute; left: 50%; top: 50%; width: calc(94 * var(--u)); aspect-ratio: 1; border-radius: calc(11 * var(--u));
  object-fit: cover; background: #2C2C2E; box-shadow: 0 calc(10 * var(--u)) calc(22 * var(--u)) rgb(0 0 0 / 0.55); }
.join-fan img:nth-child(1) { transform: translate(calc(-50% - 112 * var(--u)), calc(-50% + 10 * var(--u))) rotate(-11deg); }
.join-fan img:nth-child(2) { transform: translate(calc(-50% - 38 * var(--u)), calc(-50% - 3 * var(--u))) rotate(-4deg); z-index: 2; }
.join-fan img:nth-child(3) { transform: translate(calc(-50% + 38 * var(--u)), calc(-50% - 3 * var(--u))) rotate(4deg); z-index: 1; }
.join-fan img:nth-child(4) { transform: translate(calc(-50% + 112 * var(--u)), calc(-50% + 10 * var(--u))) rotate(11deg); }
@container (max-height: 56px) { .join-fan img { display: none; } }
.join-form { display: grid; gap: 0.75rem; }
.join-form[hidden] { display: none; }
/* Store badges under the form, the same height (Google: at least as big as the others), side by side: the Turkish
   App Store badge is the widest, 44pt keeps the pair inside the sheet. */
.stores { display: flex; flex-wrap: wrap; justify-content: center; gap: calc(8 * var(--pt)); margin-top: calc(16 * var(--pt)); }
.stores p { flex-basis: 100%; margin: 0; text-align: center; font-size: var(--type-small); color: var(--ink-3); }
.stores img { height: calc(44 * var(--pt)); width: auto; }
.no-stores .stores { display: none; }   /* main.js: no room above the fine print */
.join-line { margin: 0; max-width: 30ch; font-size: var(--type-ui); line-height: 1.45; color: var(--ink-2); }
#email {
  width: 100%; box-sizing: border-box; height: 50px; padding: 0 1rem; border-radius: 12px;
  border: 1px solid rgb(255 255 255 / 0.08); background: var(--field); color: #fff; font-family: var(--body);
  caret-color: var(--red); -webkit-appearance: none; appearance: none;
  transition: border-color 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out);
}
#email::placeholder { color: rgb(255 255 255 / 0.55); }
#email:focus { outline: none; border-color: var(--red); box-shadow: 0 0 0 3px rgb(255 255 255 / 0.18); }
#email[aria-invalid="true"] { border-color: #ff8a80; }
.consent { display: grid; grid-template-columns: 22px 1fr; gap: 0.7rem; align-items: start; font-size: var(--type-ui); line-height: 1.4; color: var(--ink-2); cursor: pointer; }
.consent input {
  -webkit-appearance: none; appearance: none; margin: 0; width: 22px; height: 22px; border-radius: 7px;
  border: 1.5px solid rgb(255 255 255 / 0.4); background: transparent; display: grid; place-items: center; cursor: pointer;
}
.consent input::after {
  content: ""; width: 12px; height: 12px; opacity: 0; transform: scale(0.6);
  background: #fff; clip-path: polygon(14% 52%, 0 66%, 38% 100%, 100% 22%, 86% 8%, 38% 72%);
  transition: opacity 0.15s var(--ease-out), transform 0.2s var(--ease-out);
}
.consent input:checked { background: var(--red-fill); border-color: var(--red-fill); }
.consent input:checked::after { opacity: 1; transform: scale(1); }
.join-error { margin: 0; min-height: 1.2em; font: 600 var(--type-small)/1.3 var(--body); color: #ff9b91; }
.join-error:empty { min-height: 0; }
.slide { box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.06); cursor: pointer; }
.slide-text { position: relative; z-index: 1; font: 600 var(--type-ui)/1 var(--body); letter-spacing: 0.01em; }   /* centered across the track, like the app */
/* Like the app's slider: --x is the knob's travel, --p the share of it (0..1). The knob and the trail behind it
   go from red to green with --p; past 80% the chevrons turn into a check. */
@property --x { syntax: '<length>'; inherits: true; initial-value: 0px; }
@property --p { syntax: '<number>'; inherits: true; initial-value: 0; }
.slide { --tint: color-mix(in oklch, var(--red-fill), #30D158 calc(var(--p) * 100%));
         transition: --x 0.35s cubic-bezier(0.32, 0.72, 0, 1), --p 0.35s cubic-bezier(0.32, 0.72, 0, 1); }
.slide.is-dragging { transition: none; }
.slide::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--x) + 52px); border-radius: inherit;
  background: linear-gradient(90deg, color-mix(in srgb, var(--tint) 70%, transparent), color-mix(in srgb, var(--tint) 40%, transparent)); }
.slide-knob { background: var(--tint); transform: translateX(var(--x)); box-shadow: 0 4px 12px -4px rgb(0 0 0 / 0.7); }
.slide-knob svg { grid-area: 1 / 1; width: 22px; height: 22px; transition: opacity 0.15s; }
.slide-knob .knob-check, .slide.is-past .knob-chev { opacity: 0; }
.slide.is-past .knob-check { opacity: 1; }
/* Fine print: a page footer, outside the phone. Wide screens: bottom right, beside the phone. Portrait: a band
   along the bottom edge; the phone runs under it and the sign-up sheet ends above it (main.js). */
.legal { position: fixed; z-index: 3; right: var(--edge); bottom: max(16px, env(safe-area-inset-bottom)); margin: 0; text-align: right;
  max-width: calc(50vw - var(--phone-h) * 0.249 - var(--edge) - 24px);
  font-size: var(--type-small); line-height: 1.5; color: var(--ink-2); text-shadow: 0 1px 8px rgb(0 0 0 / 0.8); pointer-events: none; }
.is-join .legal, .no-story .legal { pointer-events: auto; }
.nowrap { white-space: nowrap; }
@media (orientation: portrait) {
  .legal { left: 0; right: 0; bottom: 0; max-width: none; text-align: center;
           padding: 18px 16px max(12px, env(safe-area-inset-bottom)); background: linear-gradient(transparent, rgb(8 4 2 / 0.94) 40%); }
}
.join-done { padding-top: 0.5rem; outline: none; text-align: center; animation: rise-in 0.45s var(--ease-out) backwards; } /* runs when [hidden] lifts */
@keyframes rise-in { from { opacity: 0; transform: translateY(8px); } }
@media (prefers-reduced-motion: reduce) { .join-done { animation-name: fade-in; } }
.done-title { margin: 0 0 0.6rem; font: 700 2rem/1.05 var(--display); letter-spacing: -0.02em; }
.join-done p:last-child { margin: 0; font-size: var(--type-ui); color: var(--ink-2); line-height: 1.5; }


/* Phones (portrait): the same centered slot, between the bar and the phone's top edge */
@media (orientation: portrait) {
  .ui::before { background: linear-gradient(180deg, rgb(8 4 2 / 0.8) 0%, rgb(8 4 2 / 0.6) 23%, rgb(8 4 2 / 0.2) 33%, transparent 41%, transparent 58%, rgb(8 4 2 / 0.8) 100%); }
  .side { --band-bottom: calc(26svh - 8px); }
  :root { --type-xl: clamp(2.2rem, 10.5vw, 3.4rem); --type-m: clamp(1.25rem, 5.6vw, 1.7rem); --type-ui: 0.85rem; }
  .checkin-art { height: calc(140 * var(--pt)); }   /* lifts the check-in slider clear of Safari's bottom bar */
  .soon-title { margin-bottom: 0.5rem; }
  .contact { margin-bottom: 0.25rem; max-width: none; }
  .bar-logo { height: 24px; }
  .bar-join { padding: 0.65em 0.95em; }
  .screen { padding-top: 15cqh; }
}
@media (prefers-reduced-motion: reduce) { .hint-icon { animation: none; } }

/* Privacy notice (Read mode): the same black and red, a calm single column */
body.doc { background: #0b0806; }
.doc-main { max-width: 68ch; margin: 0 auto; padding: max(28px, env(safe-area-inset-top)) var(--edge) 96px; line-height: 1.65; color: var(--ink-2); }
.doc-home img { height: 30px; width: auto; display: block; }
.doc-lang { margin: 1.2rem 0 2.6rem; font-size: 0.85rem; color: var(--ink-3); }
.doc-main article + article { margin-top: 4.5rem; padding-top: 3rem; border-top: 1px solid rgb(255 255 255 / 0.1); }
.doc-main h1 { font: 700 clamp(2rem, 6vw, 3rem)/1.1 var(--display); letter-spacing: -0.02em; color: #fff; margin: 0 0 0.8rem; }
.doc-main h2 { font: 600 1.25rem/1.35 var(--body); color: #fff; margin: 2.2rem 0 0.4rem; }
.doc-main p { margin: 0 0 0.8rem; }
.doc-lead { font-size: 1.05rem; color: var(--ink-2); }
.doc-main a { color: #fff; }
.version { margin-top: 2rem; font-size: 0.8rem; color: var(--ink-3); }

/* Short phones (iPhone SE class): keep the whole sign-up, slider included, on screen */
@media (orientation: portrait) and (max-height: 720px) {
  .phone { top: 27.5svh; }
  .side { --band-bottom: calc(27.5svh - 8px); }
  .intro { margin-top: 5svh; }   /* the statement-size headline and its scroll cue stay clear of the TV */
  .soon-title { margin-bottom: 0.3rem; }
  .join-icon { display: none; }
  .screens .screen-join { padding-top: calc(56 * var(--pt)); }   /* room for the store badges above the fine print */
  .stores { margin-top: calc(10 * var(--pt)); }
  .brush { width: 74%; }
  .join-form { gap: 0.55rem; margin-top: calc(14 * var(--pt)); }
}
/* The smallest phones (iPhone SE in Safari, 320px-wide zoomed displays): the headline and its scroll cue sit higher still */
@media (orientation: portrait) and (max-height: 640px) {
  :root { --type-xl: clamp(2rem, min(10.5vw, 6.5svh), 3.4rem); }   /* the statement size minds the height too */
  .intro { margin-top: 2svh; }
  .hint { margin-top: 0.8rem; }
}
/* Touch: tap areas reach 44px tall around the small controls and links without changing how they look */
@media (pointer: coarse) {
  .bar-join, .lang button, .contact a, .privacy-link { position: relative; }
  .bar-join::after, .lang button::after, .contact a::after, .privacy-link::after { content: ""; position: absolute; inset: -9px 0; }
  .contact a::after, .privacy-link::after { inset: -13px 0; }
}
/* Phones held sideways: a shorter phone so one-line captions fit above it; the sign-up screen scrolls by itself. */
@media (orientation: landscape) and (max-height: 520px) {
  /* The phone is big enough to hide the TV and runs off the bottom edge, like on upright phones; the text sits above it. */
  :root { --phone-h: 82svh; }
  .phone { bottom: auto; top: 31svh; }
  .side { --band-top: calc(max(12px, env(safe-area-inset-top)) + 46px); --band-bottom: calc(31svh - 6px); }
  .intro { margin-top: 0; }
  :root { --type-xl: clamp(1.8rem, 4.4vw, 2.6rem); }
  .hint { margin-top: 0.8rem; }
  .subline { margin-top: 0.3em; }   /* keeps the punchline clear of the TV */
  .soon-title { font-size: var(--type-m); margin-bottom: 0.2rem; }   /* the band above the phone is too short for a statement and the contact line */
  .contact { font-size: var(--type-small); margin-bottom: 0; }
  .screens .screen-join { padding: calc(60 * var(--pt)) 5cqw 6cqh; }
  .join-icon, .join-fan { display: none; }
  .join-form { margin-top: calc(16 * var(--pt)); }
  .join-line, .consent, .slide-text { font-size: var(--type-small); }   /* the smallest role, never below it */
  .consent { gap: 0.5rem; }
  .slide-text { display: block; padding-left: 3.25rem; line-height: 1.15; }   /* may wrap to two lines, both clear of the knob: on one line it pushed the form wider than the screen */
}
