/* ============================================================================
   Tiny Tinfle: the front door at / (the approved direct-action design,
   TinyTinfle_Handoff/). Warm paper, serif headlines, clean sans controls,
   one main action per state. Standalone: this page loads no landing kit.
   Light only, like the approved screens. Mobile-first; on wide screens the
   same column centers.

   Contrast (the handoff asks to fix, not copy, weak pairs): the mockup's
   coral on paper is 3.0:1 and white on coral 3.0:1, so small coral TEXT
   uses --tt-coral-text (5.4:1), the big italic headline accent uses
   --tt-coral-big (3.8:1, AA for large text), and coral buttons carry ink
   text (5.4:1, the site's own coral-button pairing).
   ========================================================================== */
:root {
    --tt-paper: #FFFDF8;
    --tt-ink: #211F1E;
    --tt-coral: #F26956;
    --tt-coral-big: #E0533F;
    --tt-coral-text: #B8402C;
    --tt-navy: #222830;
    --tt-muted: #6E6A65;
    --tt-line: #E9E3DA;
    --tt-card: #F4EFE8;
    --tt-serif: 'Source Serif 4', Georgia, 'Times New Roman', serif;
    --tt-sans: Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
    --tt-radius: 16px;
    --tt-col: 440px;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body.tt {
    margin: 0;
    min-height: 100vh;
    background: var(--tt-paper);
    color: var(--tt-ink);
    font-family: var(--tt-sans);
    font-size: 16px;
    line-height: 1.5;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.tt [hidden] { display: none !important; }
.tt a { color: var(--tt-coral-text); }
.tt :focus-visible { outline: 3px solid var(--tt-coral-text); outline-offset: 2px; }
/* Headings take focus on every screen change (so screen readers land on
   the new state); that is not a keyboard target, so no ring */
.tt .tt-h:focus, .tt .tt-h:focus-visible { outline: none; }
/* The same for a card that takes focus in place of a title */
.tt .tt-view:focus, .tt .tt-view:focus-visible { outline: none; }

/* ----- header: the brand + the account icon (Your cards) ----- */
.tt-head {
    width: 100%;
    max-width: var(--tt-col);
    padding: 20px 22px 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
/* The real Tinfle brand, as the landing sets it: the brick-T mark, the
   wordmark (.nav-word: Bricolage Grotesque 800, capital T; the font is
   subset to those six letters, so it stays on .tt-word only) and the
   pronunciation note (.nav-pron). The note sits on a second line under
   the word: inline it would not fit beside the account icon on a small
   phone (the landing just hides it below 440px). */
.tt-brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px; /* a 44px touch target (it links home) */
    flex-shrink: 0;
    color: var(--tt-ink) !important;
    text-decoration: none;
}
.tt-brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.1;
}
.tt-word {
    font-family: "Bricolage Grotesque", var(--tt-sans);
    font-weight: 800;
    font-size: 1.3rem;
    letter-spacing: -0.02em;
    white-space: nowrap;
    flex-shrink: 0;
}
.tt-pron {
    font-family: var(--tt-sans);
    font-weight: 500;
    font-size: 0.72rem;
    color: var(--tt-muted);
    white-space: nowrap;
}
.tt-brand-mark {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
}
/* Your cards: history, purchases, kept reaction videos (tiny-send.js hides
   it mid-send, when leaving would drop the unsent video) */
.tt a.tt-account {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 1.5px solid var(--tt-line);
    background: #FFFFFF;
    color: var(--tt-ink);
    text-decoration: none;
    transition: border-color 0.15s ease;
}
.tt a.tt-account:hover { border-color: #D6CEC3; }
/* The "What they see" label on the recipient-preview overlay */
.tt-status {
    min-width: 0;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--tt-muted);
    text-align: right;
}

/* ----- the column: ONE page ----- */
/* 2026-10-01 (founder, second pass): the headline never moves and the
   video lands inside the box, so the column is one stack (headline, box,
   the video's file row, the steps bar, then the carousel area) with the
   same top spacing in every state. The horizontal clip holds the carousel:
   a screen slides in from one side while the last one slides out the
   other, clipped at the column so nothing pans the page sideways. clip,
   not hidden: hidden would make the column a scroll box. */
.tt-main {
    width: 100%;
    max-width: var(--tt-col);
    padding: 18px 22px 16px;
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
    gap: 14px;
    overflow-x: clip;
}
@supports not (overflow-x: clip) { .tt-main { overflow-x: hidden; } }
/* The carousel area: the screen on its way out is lifted out of the flow
   at the top of the area, so the incoming one takes its place */
.tt-deck { position: relative; display: flex; flex-direction: column; }
.tt-view.tt-leaving { position: absolute; top: 0; left: 0; margin: 0; pointer-events: none; }
.tt-view { display: flex; flex-direction: column; gap: 18px; }
.tt-copy { display: flex; flex-direction: column; gap: 10px; }
/* The headline section is centered (founder 2026-10-01): the text is
   centered inside full-width lines, so nothing resizes when the web font
   arrives (the headline must never move) */
.tt-hero { text-align: center; }
/* Balanced lines: "Get their first reaction back." (2026-10-14) wraps on
   every width, and unbalanced it left "back." alone on its own line.
   Chrome does not balance a block that holds a <br>, so the coral line is a
   block of its own instead of a break (the sub text is one sentence since
   2026-10-16, balanced on its own) */
.tt-hero .tt-h, .tt-hero .tt-lede { text-wrap: balance; }
/* What people send (founder 2026-10-17, the pills replaced the same day:
   "I do not like this at all"): the six search phrases as a NEWS TICKER
   under the headline. The strip runs edge to edge of the column (the
   negative margins undo .tt-main's side padding), fades at both ends, and
   the track (the real list + its aria-hidden copy, each half the width)
   rolls right to left in 20s (the founder's "Faster"), the "Quiet" look:
   muted text, small coral dots, hairlines above and below. Plain text,
   never buttons: no pointer, no focus stop. Held still while touched or
   hovered (tiny-send.js adds .is-held). Reduced motion: no roll, the six
   phrases standing still in one centered line, the copy hidden. */
.tt-ticker {
    position: relative;
    overflow: hidden;
    margin: 6px -22px 0;
    padding: 9px 0;
    border-top: 1px solid var(--tt-line);
    border-bottom: 1px solid var(--tt-line);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}
.tt-ticker-track {
    display: flex;
    width: max-content;
    animation: tt-ticker-roll 20s linear infinite;
}
.tt-ticker.is-held .tt-ticker-track { animation-play-state: paused; }
.tt-keywords {
    display: flex;
    margin: 0;
    padding: 0;
    list-style: none;
}
.tt-keywords li {
    display: flex;
    align-items: center;
    padding-right: 22px;
    color: var(--tt-muted);
    font-size: 0.92rem;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
}
.tt-keywords li::before {
    content: "";
    flex: 0 0 auto;
    width: 5px;
    height: 5px;
    margin-right: 14px;
    border-radius: 50%;
    background: var(--tt-coral);
}
/* Halloween (2026-10-21): the free line leads the strip, in coral */
.tt-keywords li.tt-kw-season { color: var(--tt-coral-text); font-weight: 700; }
@keyframes tt-ticker-roll { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
    .tt-ticker-track { animation: none; width: auto; justify-content: center; }
    .tt-keywords { flex-wrap: wrap; justify-content: center; row-gap: 6px; }
    .tt-keywords + .tt-keywords { display: none; }
}
.tt-hero .tt-h em { display: block; }
/* Halloween (2026-10-21, founder): a few bats around the headline while the
   Halloween offer is presented (the server unhides .tt-deco, services/
   seasonalHome.js). Out of the flow (absolute, an absolute flex child takes
   no gap), behind nothing, never a tap target: the headline does not move.
   They bob gently; still under reduced motion. */
.tt-hero { position: relative; }
.tt-deco { position: absolute; inset: 0; pointer-events: none; }
.tt-bat {
    position: absolute;
    height: auto;
    animation: tt-bat-bob 2.8s ease-in-out infinite alternate;
}
/* In the side space of the headline's lines (clear of the header's brand,
   flags and account icon): two at the left of the first line, one at the
   right of the second */
.tt-bat--1 { width: 34px; left: 0; top: 24px; transform: rotate(-12deg); }
.tt-bat--2 { width: 28px; right: 0; top: 66px; transform: rotate(10deg); animation-delay: -1.1s; }
.tt-bat--3 { width: 18px; left: 40px; top: 8px; transform: rotate(-6deg); animation-delay: -2s; opacity: 0.8; }
@keyframes tt-bat-bob { to { translate: 0 -6px; } }
@media (prefers-reduced-motion: reduce) { .tt-bat { animation: none; } }
/* A narrow phone's lines run wider: smaller bats, the third one out */
@media (max-width: 359px) {
    .tt-bat--1 { width: 24px; left: -6px; }
    .tt-bat--2 { width: 22px; right: -6px; }
    .tt-bat--3 { display: none; }
}
.tt-eyebrow {
    margin: 0;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--tt-coral-text);
}
.tt-h {
    margin: 0;
    font-family: var(--tt-serif);
    font-weight: 400;
    font-size: clamp(2.1rem, 9vw, 2.55rem);
    line-height: 1.08;
    letter-spacing: -0.015em;
    color: var(--tt-ink);
    outline: none;
}
.tt-h em { font-style: italic; color: var(--tt-coral-big); }
/* The titles inside the carousel area: smaller, so the headline above
   stays the one big line on the page */
.tt-h.tt-h2 { font-size: clamp(1.55rem, 6.6vw, 1.85rem); line-height: 1.12; }
.tt-lede { margin: 0; font-size: 0.98rem; line-height: 1.55; color: var(--tt-muted); }
.tt-small { margin: 0; font-size: 0.8rem; line-height: 1.5; color: var(--tt-muted); text-align: center; }
.tt-msg { margin: 0; min-height: 0; font-size: 0.88rem; line-height: 1.45; color: var(--tt-coral-text); text-align: center; }
.tt-msg:empty { display: none; }
.tt-msg.is-info { color: var(--tt-muted); }
.tt-error { margin: 0; font-size: 0.9rem; line-height: 1.45; color: var(--tt-coral-text); }

/* ----- the proof line (shield + one sentence) ----- */
.tt-proof {
    margin: 0;
    display: flex;
    gap: 8px;
    align-items: flex-start;
    font-size: 0.8rem;
    line-height: 1.45;
    color: var(--tt-muted);
}
.tt-proof svg { flex: 0 0 auto; margin-top: 1px; color: var(--tt-coral-text); }

/* ----- 01: the demonstration (founder 2026-10-06) ----- */
/* What she sent -> what came back, in two phone frames side by side at
   every width (never stacked). The right one is the payoff: a little
   larger, its label coral. The frames are plain CSS: a thin near-black
   bezel, large rounded corners and the 9:16 video clipped to the screen;
   no shadows, gradients or hardware, one small camera dot. The radii are
   percentages of each box (horizontal / vertical), so the corners stay
   round at any size: the phone is 1.737 times as tall as wide, the screen
   1.778. It replaced the navy photo card ("Send a video", the envelope and
   the rotating occasion photos); its two buttons moved under it. */
.tt-startblock { display: flex; flex-direction: column; gap: 24px; }
/* THE START SCREEN FITS ONE SCREEN (founder 2026-10-18, option B of a
   measured comparison: "there really is no reason to scroll up or down").
   Tighter spacing on the start screen only (about 65px in all), and the
   demonstration row never wider than what the screen height leaves for it:
   everything else on the start screen is about 438px tall after these cuts
   and the row is 0.824 as tall as it is wide. This is the first paint;
   tiny-send.js fitStart then measures the real remainder and sets the
   width exactly (inline), never below the 220px floor (phones about 150px
   tall: a very short screen keeps a short scroll instead), never wider than
   the column. A Pixel 7 or a full-screen iPhone keeps the full size. */
/* The homepage's main column starts 8px under the header (was 18) in EVERY
   state (body.tt-app, never toggled): a start-only cut would move the
   headline when the video comes in. Only the sender app: How it works,
   Pricing, the 404, /r and the login pages keep their 18px. The two 14px
   gaps around the demonstration close to 8px with margins on the start
   screen only. */
body.tt-app .tt-main { padding-top: 8px; }
body.tt-at-start #tt-startblock, body.tt-at-start #tt-deck { margin-top: -6px; }
body.tt-at-start .tt-ticker { margin-top: 2px; padding: 6px 0; }
body.tt-at-start #tt-view-start { gap: 8px; }
body.tt-at-start .tt-startblock { gap: 12px; }
body.tt-at-start .tt-demo { gap: 10px; }
body.tt-at-start .tt-demo-item { gap: 5px; }
body.tt-at-start .tt-demo-mid { margin-top: 18px; gap: 6px; }
body.tt-at-start .tt-make { gap: 8px; }
body.tt-at-start .tt-make-h { font-size: 1.25rem; }
body.tt-at-start .tt-foot-price { margin-top: 4px; }
body.tt-at-start .tt-demo-row { max-width: max(220px, calc((100svh - 438px) * 1.21)); }
.tt-demo { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.tt-demo-row { width: 100%; display: flex; justify-content: center; align-items: flex-start; gap: 6px; }
.tt-demo-item { margin: 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 8px; }
/* The phones share what the middle column leaves, the right one 1.13x */
.tt-demo-item--sent { width: calc((100% - 60px) * 0.47); }
.tt-demo-item--back { width: calc((100% - 60px) * 0.53); }
.tt-demo-label {
    margin: 0;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--tt-muted);
}
.tt-demo-label--back { color: var(--tt-coral-text); }
/* Between the phones, centered on them (the labels sit above): the arrow,
   and under it the one control for both. Under the phones it fell below
   the first screen on an iPhone SE, small Androids and a 1366 laptop. */
.tt-demo-mid { flex: 0 0 auto; align-self: center; margin-top: 24px; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.tt-demo-arrow { display: block; color: var(--tt-muted); }
.tt-phone { width: 100%; padding: 2.6%; background: #16171A; border-radius: 13% / 7.48%; }
.tt-phone-screen { position: relative; overflow: hidden; isolation: isolate; border-radius: 11% / 6.17%; background: #000; }
.tt-phone-video { display: block; width: 100%; height: auto; aspect-ratio: 9 / 16; object-fit: cover; }
/* The Tinfle logo on the demo phones (2026-10-20, founder): where every
   real Tinfle carries it (services/cardLogo.js burns it into the card
   video's top-left corner at 8% of the width, and the reaction copy keeps
   it), drawn by the page over the video so it stays crisp at any size.
   4.5% in rather than the video's 2.4%: the screen's rounded corner would
   clip it. Percent margins resolve against the screen's WIDTH. */
.tt-demo-logo {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    width: max(14px, 8%);
    height: auto;
    margin: max(5px, 4.5%);
    pointer-events: none;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
}
.tt-phone-screen::after {
    /* the camera: a small dot at the top of the screen */
    content: "";
    position: absolute;
    top: 2.2%;
    left: 50%;
    z-index: 1;
    width: 3.6%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: #16171A;
    transform: translateX(-50%);
}
/* One control for both videos: play, pause, play again, with a thin ring
   that fills as they play (tiny-demo.js sets data-state and the ring) */
.tt-demo-play {
    position: relative;
    width: 46px;
    height: 46px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #FFFFFF;
    color: var(--tt-ink);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.tt-demo-ring { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.tt-demo-ring-track { fill: none; stroke: #CFC7BC; stroke-width: 1.5; }
.tt-demo-ring-fill { fill: none; stroke: var(--tt-coral); stroke-width: 2.5; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0; }
.tt-demo-icon { position: relative; display: none; }
.tt-demo-play[data-state="paused"] .tt-demo-icon--play { display: block; margin-left: 2px; }
.tt-demo-play[data-state="playing"] .tt-demo-icon--pause,
.tt-demo-play[data-state="ended"] .tt-demo-icon--again { display: block; }
/* Once they ended, the word under the button (2026-10-14): placed under
   the circle without taking room, so nothing around it moves */
.tt-demo-again-text {
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    display: none;
    transform: translateX(-50%);
    font-family: var(--tt-sans);
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    color: var(--tt-ink);
}
.tt-demo-play[data-state="ended"] .tt-demo-again-text { display: block; }
/* The sound control (founder 2026-10-15, minimal): the speaker alone, in
   the bottom-right corner of the What came back screen, clear of Mom's
   window (top right) and of the burned-in captions (bottom center). The
   button is the 44px target, transparent, in the screen's corner; the dot
   in it is what shows, 6px from the edges (white on the dark dot is 5:1 or
   more over any frame). Small on purpose: at 30px it reached into the
   captions on a 390 phone and covered them at 320. It was a "Tap for
   sound" pill on the phone's bottom edge (2026-10-14). */
.tt-demo-sound {
    position: absolute;
    right: 0;
    bottom: 0;
    z-index: 2;
    display: inline-flex;
    align-items: flex-end;
    justify-content: flex-end;
    width: 44px;
    height: 44px;
    padding: 6px;
    border: 0;
    background: none;
    color: #FFFFFF;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.tt-demo-sound-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(22, 23, 26, 0.62);
}
.tt-demo-sound-dot svg { width: 14px; height: 14px; }
@media (max-width: 359px) {
    .tt-demo-sound-dot { width: 22px; height: 22px; }
    .tt-demo-sound-dot svg { width: 12px; height: 12px; }
}
.tt-demo-sound:focus-visible { outline: none; }
.tt-demo-sound:focus-visible .tt-demo-sound-dot { box-shadow: 0 0 0 2px #FFFFFF, 0 0 0 4px var(--tt-coral-text); }
.tt-demo-sound-icon { display: none; flex: 0 0 auto; }
.tt-demo-sound[data-sound="off"] .tt-demo-sound-icon--off,
.tt-demo-sound[data-sound="on"] .tt-demo-sound-icon--on { display: block; }

/* ----- the creation actions, under the demonstration ----- */
/* Choose a video (the page's coral main action) and Record one: the same
   label + input and button as before, on the paper now */
.tt-make { display: flex; flex-direction: column; gap: 12px; }
.tt-make-h { margin: 0; text-align: center; font-family: var(--tt-serif); font-weight: 400; font-size: 1.4rem; line-height: 1.2; color: var(--tt-ink); }
.tt-make-actions { position: relative; display: flex; flex-direction: column; gap: 10px; }
/* The input stays in the tree (the label opens it without JS) but never shows */
.tt-file-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.tt-make-actions:focus-within .tt-pick { outline: 3px solid var(--tt-coral-text); outline-offset: 2px; }
/* The Android sheet behind the one button (founder 2026-10-15; tiny-choose.js
   moves it to the body and shows it on Android only): Record a video / Choose
   from your phone / Cancel, on paper, up from the bottom like a phone's own
   menu */
.tt-choose {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgba(33, 31, 30, 0.45);
}
.tt-choose-sheet {
    width: 100%;
    max-width: 480px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 16px 16px calc(12px + env(safe-area-inset-bottom, 0px));
    border-radius: 20px 20px 0 0;
    background: var(--tt-paper);
    animation: tt-choose-up 200ms ease-out;
}
.tt-choose-sheet:focus { outline: none; }
@keyframes tt-choose-up { from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } }
.tt-choose-row {
    display: flex;
    align-items: center;
    gap: 14px;
    min-height: 56px;
    padding: 0 18px;
    border: 1.5px solid var(--tt-line);
    border-radius: 14px;
    background: #FFFFFF;
    color: var(--tt-ink);
    font: inherit;
    font-size: 1rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}
.tt-choose-row svg { flex: 0 0 auto; color: var(--tt-coral-text); }
.tt-choose-cancel {
    min-height: 48px;
    border: 0;
    background: none;
    color: var(--tt-muted);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.tt-choose-row:focus-visible, .tt-choose-cancel:focus-visible { outline: 3px solid var(--tt-coral-text); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .tt-choose-sheet { animation: none; } }
/* The jumpscare picker (2026-10-21): its row in the start button's sheet
   (a jack-o'-lantern in place of the row icon) and the picker: the pool's
   clips as 9:16 tiles, two across, each with its own Use this one */
.tt-scare-jack { width: 26px; height: auto; flex: 0 0 auto; }
.tt-scares {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgba(33, 31, 30, 0.45);
}
.tt-scares-sheet {
    width: 100%;
    max-width: 480px;
    max-height: 90vh;
    max-height: 90svh;
    overflow-y: auto;
    overscroll-behavior: contain;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 16px 16px calc(16px + env(safe-area-inset-bottom, 0px));
    border-radius: 20px 20px 0 0;
    background: var(--tt-paper);
    animation: tt-choose-up 200ms ease-out;
}
.tt-scares-sheet:focus { outline: none; }
.tt-scares-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tt-scares-h { margin: 0; font-family: var(--tt-serif); font-weight: 400; font-size: 1.5rem; line-height: 1.2; color: var(--tt-ink); }
.tt-scares-x {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    margin-right: -8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--tt-ink);
    cursor: pointer;
}
.tt-scares-sub { margin: 0; font-size: 0.92rem; line-height: 1.45; color: var(--tt-muted); }
.tt-scares .tt-msg:empty { display: none; }
.tt-scares-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 12px;
    margin: 8px 0 0;
    padding: 0;
    list-style: none;
}
.tt-scare { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.tt-scare-video {
    display: block;
    width: 100%;
    aspect-ratio: 9 / 16;
    height: auto;
    border-radius: 12px;
    background: var(--tt-navy);
    object-fit: cover;
}
.tt-scare-use { min-height: 44px; font-size: 0.92rem; }
@media (prefers-reduced-motion: reduce) { .tt-scares-sheet { animation: none; } }

/* ----- the box: the sender's video, once it is in ----- */
/* Hidden on the start screen. With a video it takes the start block's
   place and stays put through every step: a 9:16 frame at 75% of a phone's
   column (200px floor, 290px cap; 240px on laptops), centered, the video
   layer (#tt-tile) covering all of it. */
.tt-drop {
    position: relative;
    overflow: hidden;
    border-radius: 20px;
    background: var(--tt-navy);
    color: #FFFFFF;
    width: clamp(200px, 75%, 290px);
    align-self: center;
    aspect-ratio: 9 / 16;
    min-height: 236px;
}
.tt-drop-video { position: absolute; inset: 0; z-index: 3; background: var(--tt-navy); }
.tt-foot-price { margin-top: 12px; }
/* The price line is a link to /pricing (membership, 2026-10-08): a 44px
   target that does not move the line (the negative margins give the
   height back), on the homepage and on /how-it-works alike. */
[data-tt-price] a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    margin: -14px 0;
    padding: 0 4px;
}
/* ----- the video in the box ----- */
/* PORTRAIT (2026-09-30): a phone-shaped 9:16 tile. Upright videos fill it;
   sideways ones show with bars (object-fit: contain). Since 2026-10-01 the
   sender's video plays inside the box itself (.tt-drop-video, #tt-tile).
   The "See what they see" overlay that also used these was retired
   2026-10-14 (founder: irrelevant and confusing). */
.tt-tile {
    position: relative;
    overflow: hidden;
    border-radius: var(--tt-radius);
    background: var(--tt-navy);
    aspect-ratio: 9 / 16;
    width: min(62%, 250px);
    align-self: center;
}
.tt-tile-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: var(--tt-navy); }
.tt-tile-badge {
    position: absolute;
    top: 12px;
    left: 14px;
    right: 12px;
    font-size: 0.64rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #FFFFFF;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.5);
    pointer-events: none;
}
/* The X that removes a picked video (founder 2026-09-30): a 44px target in
   the corner, the visible dot smaller. The dark dot keeps the white X
   readable over any frame, white ones included; the focus ring is paper
   and drawn inside the button, because the tile clips anything outside */
#tt-tile .tt-tile-badge { right: 52px; }
.tt-tile-x {
    position: absolute;
    top: 2px;
    right: 2px;
    z-index: 2;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: #FFFFFF;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.tt-tile-x-dot {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: rgba(17, 20, 24, 0.66);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.35);
    display: flex;
    align-items: center;
    justify-content: center;
}
.tt-tile-x:hover .tt-tile-x-dot { background: rgba(17, 20, 24, 0.82); }
.tt .tt-tile-x:focus-visible { outline: 3px solid var(--tt-paper); outline-offset: -3px; }
.tt-play {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 52px;
    height: 52px;
    margin: -26px 0 0 -26px;
    border-radius: 50%;
    border: 0;
    background: #FFFFFF;
    color: var(--tt-ink);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.3);
}
.tt-play svg { margin-left: 3px; }
.tt-tile-time {
    position: absolute;
    left: 14px;
    bottom: 12px;
    font-size: 0.78rem;
    font-weight: 700;
    color: #FFFFFF;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.5);
    pointer-events: none;
}
.tt-tile-note {
    position: absolute;
    inset: auto 14px 12px;
    margin: 0;
    font-size: 0.78rem;
    color: rgba(255, 255, 255, 0.85);
    text-align: center;
}
/* The video's file row, progress and notes sit under the box at its width */
.tt-vidinfo { width: clamp(200px, 75%, 290px); align-self: center; display: flex; flex-direction: column; gap: 8px; }
.tt-row { display: flex; justify-content: space-between; gap: 12px; font-size: 0.88rem; }
.tt-row b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.tt-row span { color: var(--tt-muted); white-space: nowrap; }
.tt-row span.is-ready { color: var(--tt-ink); font-weight: 600; }
.tt-row span.is-bad { color: var(--tt-coral-text); font-weight: 600; }
/* The upload status INSIDE the box (2026-10-01, founder): a dark band at the
   foot of the video while it uploads and is checked; it fades 3 seconds
   after Ready (tiny-send.js), and stays on a failure. The band darkens to
   0.86 behind the text, so the white lines keep 9:1 or better over the
   brightest frame; a failure reads in a light coral (#FFB4A8, 9:1). While
   it shows, the video's length steps aside and the browser note sits
   above it. */
.tt-tile-status {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 2;
    padding: 28px 14px 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    color: #FFFFFF;
    background: linear-gradient(rgba(17, 20, 24, 0), rgba(17, 20, 24, 0.86) 42%);
    pointer-events: none;
    transition: opacity 0.4s ease;
}
.tt-tile-status.is-leaving { opacity: 0; }
.tt-tile-status .tt-row { font-size: 0.82rem; }
.tt-tile-status .tt-row b { color: #FFFFFF; }
.tt-tile-status .tt-row span { color: rgba(255, 255, 255, 0.86); }
.tt-tile-status .tt-row span.is-ready { color: #FFFFFF; font-weight: 700; }
.tt-tile-status .tt-row span.is-bad { color: #FFB4A8; font-weight: 700; }
.tt-tile-status .tt-progress { background: rgba(255, 255, 255, 0.28); }
#tt-tile.has-status .tt-tile-time { opacity: 0; }
#tt-tile.has-status .tt-tile-note { bottom: 76px; }
/* Under the box only notes remain: no empty gap when there are none */
.tt-vidinfo:not(:has(> :not([hidden]))) { display: none; }
.tt-progress { height: 4px; border-radius: 999px; background: var(--tt-line); overflow: hidden; }
.tt-progress span { display: block; height: 100%; width: 0; background: var(--tt-coral); transition: width 0.2s ease; }
/* The safety check has no real percentage: the bar creeps toward the end
   over a long ease-out, and Ready (a 0.2s fill) finishes it */
.tt-progress span.is-checking { transition: width 40s cubic-bezier(0.15, 0.6, 0.3, 1); }
.tt-upfail { display: flex; flex-direction: column; gap: 10px; }

/* ----- fields ----- */
.tt-field { display: flex; flex-direction: column; gap: 6px; }
.tt-field label, .tt-themes legend {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--tt-ink);
}
.tt-field label span, .tt-themes legend span { color: var(--tt-muted); font-weight: 600; }
.tt-field input, .tt-field textarea {
    width: 100%;
    font: inherit;
    font-size: 1rem;
    color: var(--tt-ink);
    background: transparent;
    border: 0;
    border-bottom: 1.5px solid var(--tt-line);
    border-radius: 0;
    padding: 10px 0;
    -webkit-appearance: none;
    appearance: none;
}
.tt-field textarea { resize: vertical; min-height: 84px; border: 1.5px solid var(--tt-line); border-radius: 10px; padding: 10px 12px; }
.tt-field input::placeholder, .tt-field textarea::placeholder { color: #9A958F; }
.tt-field input:focus, .tt-field textarea:focus { outline: none; border-color: var(--tt-coral); }
/* A required field left empty at Continue (From: / To:, 2026-10-04) */
.tt-field input[aria-invalid="true"] { border-color: var(--tt-coral); }
.tt-pw { display: flex; align-items: center; gap: 8px; border-bottom: 1.5px solid var(--tt-line); }
/* Date of birth (founder 2026-10-04): typed with the number pad into a text
   field formatted MM/DD/YYYY (tiny-date.js), or picked from the calendar:
   the hidden date input lies invisible over the calendar icon, so a tap
   there opens the phone's own picker (a mouse click opens the browser's) */
.tt-date { position: relative; display: flex; align-items: center; gap: 4px; border-bottom: 1.5px solid var(--tt-line); }
.tt-date:focus-within { border-color: var(--tt-coral); }
.tt-field .tt-date .tt-date-text { border-bottom: 0; flex: 1 1 auto; min-width: 0; }
.tt-field .tt-date .tt-date-real {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 1;
    width: 44px;
    height: 100%;
    margin: 0;
    padding: 0;
    border: 0;
    opacity: 0;
    cursor: pointer;
}
.tt-date-real:hover + .tt-date-btn { background: rgba(184, 64, 44, 0.08); }
.tt-date-btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    border: 0;
    border-radius: 10px;
    background: none;
    color: var(--tt-coral-text);
    cursor: pointer;
}
.tt-date-btn:hover { background: rgba(184, 64, 44, 0.08); }
.tt-date-btn:focus-visible { outline: 3px solid var(--tt-coral-text); outline-offset: 2px; }
.tt-date-hint { margin: 6px 0 0; font-size: 0.82rem; line-height: 1.4; color: var(--tt-muted); }
.tt-pw:focus-within { border-color: var(--tt-coral); }
.tt-pw input { border-bottom: 0 !important; flex: 1; min-width: 0; }
.tt-pw-toggle { background: none; border: 0; color: var(--tt-coral-text); font: inherit; font-size: 0.85rem; font-weight: 600; cursor: pointer; padding: 10px 4px; min-height: 44px; min-width: 44px; }
.tt-check { display: flex; align-items: center; gap: 10px; font-size: 0.95rem; cursor: pointer; }
.tt-check input { width: 20px; height: 20px; accent-color: var(--tt-coral-text); }
.tt-legal { text-align: left; }
.tt-form { display: flex; flex-direction: column; gap: 16px; }

.tt-more {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: none;
    border: 0;
    padding: 8px 0;
    color: var(--tt-muted);
    font: inherit;
    font-size: 0.9rem;
    cursor: pointer;
}
.tt-more:hover { color: var(--tt-ink); }
.tt-extra { display: flex; flex-direction: column; gap: 16px; }
.tt-themes { border: 0; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.tt-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tt-chip {
    min-height: 40px;
    padding: 0 14px;
    border-radius: 999px;
    border: 1.5px solid var(--tt-line);
    background: #FFFFFF;
    color: var(--tt-ink);
    font: inherit;
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
}
.tt-chip[aria-checked="true"] { border-color: var(--tt-coral-text); background: #FDEBE6; }
/* ----- the steps bar (Video, Link, Reaction) ----- */
/* 2026-09-30 founder pick A: numbered circles joined by a line, coral up
   to where you are. 2026-10-01 (founder): it sits under the video and
   stays put while the area below slides; tiny-send.js lights the step
   they are in, labels only (the Done / Next / Their choice lines under
   them were dropped the same day). Step 1 (a video in): Video done, Link
   next. Step 2: Link filled with a soft halo. Step 3: Link done, Reaction
   lit. The line runs between the first and
   last circle centers (one sixth in from each side of a three-column
   grid) and reaches Link, then Reaction. */
.tt-stepsbar { width: 100%; margin-top: 4px; }
.tt-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); position: relative; }
.tt-steps::before,
.tt-steps::after { content: ""; position: absolute; top: 13px; height: 2px; }
.tt-steps::before { left: 16.667%; right: 16.667%; background: var(--tt-line); }
.tt-steps::after { left: 16.667%; width: 33.333%; background: var(--tt-coral); transition: width 0.38s cubic-bezier(0.22, 0.61, 0.36, 1); }
.tt-stepsbar[data-step="3"] .tt-steps::after { width: 66.667%; }
.tt-steps li { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 2px; font-size: 0.8rem; }
.tt-step-dot {
    width: 28px;
    height: 28px;
    margin-bottom: 4px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #FFFFFF;
    border: 2px solid var(--tt-line);
    color: var(--tt-muted);
    font-size: 0.8rem;
    font-weight: 700;
    transition: background 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease, color 0.25s ease;
}
.tt-step-check { display: none; }
.tt-steps b { font-weight: 700; color: var(--tt-ink); }
/* Read by screen readers only (a done step's ", done") */
.tt-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.tt-steps .is-done .tt-step-dot { background: var(--tt-coral); border-color: var(--tt-coral); color: var(--tt-ink); }
.tt-steps .is-done .tt-step-num { display: none; }
.tt-steps .is-done .tt-step-check { display: block; }
.tt-steps .is-next .tt-step-dot { border-color: var(--tt-coral); color: var(--tt-coral-text); }
.tt-steps .is-current .tt-step-dot { background: var(--tt-coral); border-color: var(--tt-coral); color: var(--tt-ink); box-shadow: 0 0 0 4px #FDEBE6; }
.tt-steps .is-current b { color: var(--tt-coral-text); }

/* ----- buttons: one main action per state ----- */
.tt-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 6px; }
.tt-primary, .tt-secondary {
    width: 100%;
    min-height: 54px;
    border-radius: 14px;
    font-family: var(--tt-sans);
    font-size: 1rem;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s ease, transform 0.1s ease;
}
.tt-primary { background: var(--tt-coral); color: var(--tt-ink); border: 0; box-shadow: 0 8px 20px rgba(242, 105, 86, 0.28); }
/* A LINK styled as the main button keeps ink text: `.tt a` (the coral link
   color) is more specific than `.tt-primary`, and left coral on coral */
.tt a.tt-primary { color: var(--tt-ink); }
.tt-primary:hover { background: #EE5C47; }
.tt-primary:active, .tt-secondary:active { transform: translateY(1px); }
.tt-primary[disabled] { opacity: 0.55; cursor: default; box-shadow: none; }
.tt-secondary { background: #FFFFFF; color: var(--tt-ink) !important; border: 1.5px solid var(--tt-line); }
.tt-secondary:hover { border-color: #D6CEC3; }
.tt-secondary--sm { min-height: 44px; font-size: 0.9rem; }
.tt-link-btn {
    align-self: center;
    background: none;
    border: 0;
    padding: 8px;
    color: var(--tt-coral-text) !important;
    font: inherit;
    font-size: 0.92rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ----- 03 / 04 ----- */
.tt-linkbox {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    border-radius: 12px;
    background: var(--tt-card);
    color: var(--tt-coral-text);
}
.tt-url {
    color: var(--tt-ink);
    font-size: 0.92rem;
    font-weight: 500;
    overflow-wrap: anywhere;
    user-select: all;
    -webkit-user-select: all;
}
.tt-success {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 6px;
    padding: 28px 20px;
    border-radius: var(--tt-radius);
    background: var(--tt-card);
    color: var(--tt-coral-text);
}
.tt-success strong { font-family: var(--tt-serif); font-weight: 400; font-size: 1.5rem; color: var(--tt-ink); }
.tt-success p { margin: 0; font-size: 0.85rem; color: var(--tt-muted); }
.tt-cards-note { text-align: center; }
/* After a Copy or a Share (2026-10-20): the old "Fingers crossed." screen as
   a block under the link screen's buttons, which stay where they are. A
   hairline sets it apart; it eases in once (nothing under reduced motion). */
.tt-after {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-top: 10px;
    padding-top: 22px;
    border-top: 1px solid var(--tt-line);
    animation: tt-after-in 0.28s ease-out;
}
.tt-after-h { margin: 0; font-family: var(--tt-serif); font-weight: 400; font-size: 1.45rem; line-height: 1.15; color: var(--tt-ink); }
.tt-after-h em { font-style: italic; color: var(--tt-coral-big); }
.tt-after .tt-success { padding: 20px 20px; }
.tt-after .tt-actions { margin-top: 0; }
@keyframes tt-after-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .tt-after { animation: none; } }

/* ----- the working spinner ----- */
.tt-spinner {
    width: 40px;
    height: 40px;
    margin: 18px auto 0;
    border-radius: 50%;
    border: 3px solid var(--tt-line);
    border-top-color: var(--tt-coral);
    animation: tt-spin 0.9s linear infinite;
}
@keyframes tt-spin { to { transform: rotate(360deg); } }

/* ----- footer ----- */
.tt-foot {
    width: 100%;
    max-width: var(--tt-col);
    padding: 18px 22px 28px;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0 14px;
    font-size: 0.8rem;
}
/* 44px touch targets, text unchanged */
.tt-foot a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    min-width: 44px;
    padding: 0 2px;
    color: var(--tt-muted);
    text-decoration: none;
}
.tt-foot a:hover { color: var(--tt-ink); text-decoration: underline; }
/* The social links (2026-10-20, founder): TikTok, Instagram, X, YouTube,
   drawn into each `data-social-links` slot by the server
   (services/socialLinks.js), 20px glyphs in 44px targets, in the footer's
   own muted color. Laptops: at the end of the footer bar, same row. Phones:
   a row of their own under the links, except on the homepage's first
   screen (under the price line there, .tt-social--start, see the rule
   after the pinned bar) and under a PINNED bar (How it works, Pricing, the
   404 page), where a second row would sit over the page for good: there
   they close the page content instead (.tt-social--page, a second slot at
   the end of main). */
.tt-social { display: inline-flex; align-items: center; justify-content: center; }
.tt-social--page,
.tt-social--start { display: none; }
/* `.tt a` paints every link coral-text; these stay the footer's muted */
.tt-social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
}
.tt .tt-social a.tt-social-link { color: var(--tt-muted); }
.tt .tt-social a.tt-social-link:hover { color: var(--tt-ink); text-decoration: none; }
.tt-social-link svg { display: block; width: 20px; height: 20px; }
.tt-social-link:focus-visible { outline: 2px solid var(--tt-coral-text); outline-offset: -2px; border-radius: 8px; }
@media (max-width: 719px) {
    .tt-foot .tt-social { flex-basis: 100%; }
    body.tt-at-start .tt-foot .tt-social { display: none; }
}
@media (max-width: 719px) and (min-height: 660px) {
    body.tt-pinfoot .tt-foot .tt-social { display: none; }
    body.tt-pinfoot .tt-social--page { display: flex; margin-top: 28px; }
}
/* EN | ES (2026-10-18, the Spanish sender app; founder the same day: "to
   the left of the profile icon"): the page's twin in the other language,
   in the HEADER beside the account icon (it sat in the footer for a few
   hours), both codes 44px targets, the current one in ink. Hidden mid-send
   with the icon (tiny-send.js), so the [hidden] rule must beat the display. */
.tt-head .tt-lang {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 0;
    min-height: 44px;
    font-size: 0.8rem;
}
.tt-head .tt-lang[hidden] { display: none; }
.tt-head .tt-lang-opt {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0 2px;
    color: var(--tt-muted);
    text-decoration: none;
    letter-spacing: 0.04em;
}
/* A flag per language since 2026-10-18 (founder: a small American flag for
   EN, a Spanish flag for ES; SVG files, never native emoji): the page's own
   language sits in a thin ink ring, the other is a little dimmed until
   hovered. The link carries the spoken name (English / Español). */
.tt-flag {
    display: block;
    width: 24px;
    height: 16px;
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(33, 31, 30, 0.16);
}
.tt-head .tt-lang-opt .tt-flag { opacity: 0.6; transition: opacity 0.15s ease; }
.tt-head .tt-lang-opt:hover .tt-flag,
.tt-head .tt-lang-opt:focus-visible .tt-flag { opacity: 1; }
.tt-head .tt-lang-opt[aria-current="true"] .tt-flag {
    opacity: 1;
    box-shadow: 0 0 0 2px var(--tt-paper, #FFFDF8), 0 0 0 3.5px var(--tt-ink);
}
.tt-head .tt-lang-opt:focus-visible { outline: 2px solid var(--tt-coral-text); outline-offset: -2px; border-radius: 6px; }
@media (prefers-reduced-motion: reduce) { .tt-head .tt-lang-opt .tt-flag { transition: none; } }
/* The start screen pins the footer bar to the bottom of the screen, so How
   it works / Help / Privacy / Terms show without scrolling. Only on screens
   at least 660px tall, or a laptop (720px+ wide) at least 620px tall: on a
   shorter phone (iPhone SE, a 360x640 Android, a phone turned sideways) a
   pinned bar would cover the upload buttons, so the footer stays at the
   end of the page there. Only on the start screen (body.tt-at-start, toggled by
   tiny-send.js): on the form screens a fixed bar would ride above the phone
   keyboard and cover the fields. How it works carries the same bar
   (body.tt-pinfoot, founder 2026-10-02: no fields there, so always). */
/* The START SCREEN pins it at EVERY height since 2026-10-18 (founder: the
   start screen fits one screen, see the fit rules above .tt-startblock, so
   the bar covers nothing); How it works keeps the height condition below. */
body.tt-at-start .tt-foot {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    max-width: none;
    padding: 0 12px env(safe-area-inset-bottom, 0px);
    gap: 0 18px;
    background: rgba(255, 253, 248, 0.96);
    border-top: 1px solid var(--tt-line);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}
body.tt-at-start .tt-main { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
@media (min-height: 660px), (min-width: 720px) and (min-height: 620px) {
    body.tt-pinfoot .tt-foot {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 20;
        max-width: none;
        padding: 0 12px env(safe-area-inset-bottom, 0px);
        gap: 0 18px;
        background: rgba(255, 253, 248, 0.96);
        border-top: 1px solid var(--tt-line);
        -webkit-backdrop-filter: blur(6px);
        backdrop-filter: blur(6px);
    }
    body.tt-pinfoot .tt-main { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
}
/* Five links since 2026-10-09 (Pricing): on phones under 400px wide the
   pinned bar tightens (gap, side padding, a hair smaller type; the 44px
   targets stay) so the five stay on one row. A second row would hide
   content behind the bar's reserved height. */
@media (max-width: 399px) {
    body.tt-at-start .tt-foot { gap: 0 8px; padding-left: 8px; padding-right: 8px; font-size: 0.76rem; }
}
@media (max-width: 399px) and (min-height: 660px) {
    body.tt-pinfoot .tt-foot { gap: 0 8px; padding-left: 8px; padding-right: 8px; font-size: 0.76rem; }
}
/* The homepage's first screen on a phone (founder 2026-10-20, "social links
   are missing from landing page", picked under the price line): the social
   links close the start screen (.tt-social--start; the footer bar keeps its
   one row). The row tucks 8px into the gap above it, and the space kept
   free above the pinned bar drops 12px, the empty part of the icons' own
   44px targets, so the screen still fits: fitStart shrinks the demo phones
   for the rest (an iPhone 14 in Safari: 186px -> 147px tall; a full-height
   iPhone keeps its size). The first-paint guess counts the row too. */
@media (max-width: 719px) {
    body.tt-at-start .tt-social--start { display: flex; margin-top: -8px; }
    body.tt-at-start .tt-main { padding-bottom: calc(52px + env(safe-area-inset-bottom, 0px)); }
    body.tt-at-start .tt-demo-row { max-width: max(220px, calc((100svh - 470px) * 1.21)); }
}


/* ----- the payment, in place (a card in the carousel, 2026-10-01) ----- */
/* Back: the site's back-button standard (a bare 24px arrow, ink, no
   circle), with its word, 44px tall */
.tt-back {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    padding: 0 8px 0 0;
    border: 0;
    background: none;
    color: var(--tt-ink);
    font: inherit;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
}
/* Stripe's form mounts here (an iframe that sizes itself); while it loads
   the box holds its place with the page's spinner */
.tt-paybox { min-height: 120px; }
.tt-paybox.is-loading { min-height: 360px; position: relative; }
.tt-paybox.is-loading::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 72px;
    width: 34px;
    height: 34px;
    margin-left: -17px;
    border-radius: 50%;
    border: 3px solid var(--tt-line);
    border-top-color: var(--tt-coral);
    animation: tt-spin 0.9s linear infinite;
}

/* The recorder overlay sits above everything on this page too */
.tt .ocr-overlay { z-index: 70; }

/* The page sits tight at the top; the same spacing in every state, so the
   headline never moves */
#tt-view-start { gap: 14px; }
/* The front door's proof line sits centered under the button (founder
   2026-10-02; "See how it works" above it left 2026-10-16); the link
   screen's proof line keeps its left alignment */
#tt-view-start .tt-proof { justify-content: center; align-items: center; text-align: center; }
@media (min-width: 720px) {
    .tt-main { padding-top: 8px; }
    /* a laptop's column is wider than a phone's: the video box stays a
       fixed 240px frame there */
    .tt-drop, .tt-vidinfo { width: 240px; }
}
/* The narrowest phones (under 360px: a first-generation iPhone SE, a Galaxy
   Fold cover screen): a smaller headline and line keep the hero short
   (measured 2026-10-05 for "You send the moment."; the 2026-10-14 headline
   "Send a video. / Get their first reaction back." is three lines here as
   on every width). */
@media (max-width: 359px) {
    .tt-hero .tt-h { font-size: 1.8rem; }
    .tt-hero .tt-lede { font-size: 0.86rem; line-height: 1.45; }
    .tt-keywords { gap: 6px; }
    .tt-keywords li { padding: 4px 10px; font-size: 0.8rem; }
}
/* The shortest screens (iPhone SE): a little tighter at the top */
@media (max-height: 619px) {
    .tt-main { padding-top: 8px; gap: 10px; }
    #tt-view-start { gap: 10px; }
    .tt-hero { gap: 8px; }
}
@media (prefers-reduced-motion: reduce) {
    .tt-spinner { animation-duration: 2.4s; }
    .tt-primary, .tt-secondary, .tt-progress span, .tt-progress span.is-checking, .tt-steps::after, .tt-step-dot, .tt-tile-status { transition: none; }
}
