/* Year in review story (review.softium.nl). Not part of the app shell: the
   app opens it full screen in a frame over itself. The palette mirrors the
   app's style.css; every color on this page comes from the variables below. */

@font-face {
    font-family: 'montserrat';
    src: url('assets/font/Montserrat-VariableFont_wght.ttf') format('truetype');
    font-weight: 100 900;
}

:root {
    color-scheme: dark;

    --bg-app: #050909;
    --bg-card: #131619;
    --bg-chip: #2B3038;
    --navy: #071730;
    --navy-light: #0b1d3d;
    --text-bright: #ffffff;
    --text-soft: #d6dbe1;
    --text-secondary: #999999;
    --accent: #0659E5;
    --accent-deep: #0442A5;
    --accent-soft: #65A3FF;
    --ink-dark: #1c1400;
    --gold: #E8C87A;
    --orange: #FF9500;
    --green: #5ECB7F;
    --red: #FF6B6B;
    --paper: #f0f0f0;
    --print-paper: #f4f1ea;
    --print-empty: #d9d4c7;
    --bar-other: #7d8794;
    --dot-off: #1a1f25;
    --divider-soft: rgba(255, 255, 255, 0.08);
    --split-track: rgba(255, 255, 255, 0.3);
    --shade-bleed: linear-gradient(180deg, rgba(5, 9, 9, 0.72) 0%, rgba(5, 9, 9, 0.25) 34%, rgba(5, 9, 9, 0.55) 58%, rgba(5, 9, 9, 0.96) 82%);
    --shade-caption: linear-gradient(180deg, rgba(5, 9, 9, 0.1) 20%, rgba(5, 9, 9, 0.9) 100%);
    --shade-quiet: linear-gradient(180deg, rgba(5, 9, 9, 0.3) 0%, rgba(5, 9, 9, 0.1) 45%, #050909 100%);
    --print-shadow: 0 10px 24px rgba(0, 0, 0, 0.35);

    /* Moves: a fast start that settles softly. Pops overshoot a little. */
    --ease-move: cubic-bezier(0.22, 0.9, 0.24, 1);
    --ease-pop: cubic-bezier(0.34, 1.56, 0.64, 1);

    /* Per slide (below): background, text, secondary text, lines and tiles */
    --slide-bg: var(--bg-app);
    --slide-ink: var(--text-bright);
    --soft-ink: var(--text-soft);
    --line: var(--divider-soft);
    --tile-bg: var(--bg-card);
}

/* The whole page takes the slide's background, so a phone with a different
   shape than the 390x844 stage never shows a band of another color. */
html[data-slide="plans"], html[data-slide="chat"] {
    --slide-bg: var(--accent);
    --soft-ink: rgba(255, 255, 255, 0.85);
    --line: rgba(255, 255, 255, 0.2);
    --tile-bg: var(--accent-deep);
}
html[data-slide="places"] {
    --slide-bg: var(--gold);
    --slide-ink: var(--ink-dark);
    --soft-ink: rgba(28, 20, 0, 0.72);
    --line: rgba(28, 20, 0, 0.22);
    --tile-bg: rgba(28, 20, 0, 0.1);
}
html[data-slide="invites"] { --slide-bg: var(--navy); --tile-bg: var(--navy-light); --line: rgba(255, 255, 255, 0.1); }
html[data-slide="photos"] { --slide-bg: var(--navy-light); --tile-bg: var(--navy); --line: rgba(255, 255, 255, 0.1); }
html[data-slide="label"] {
    --slide-bg: var(--label-bg);
    --slide-ink: var(--label-ink);
    --soft-ink: var(--label-ink);
    --line: var(--label-line);
    --tile-bg: var(--label-chip);
}

/* Label colors, one per label. Dark-ink labels share their line and chip tints. */
html[data-label="last_minute"] { --label-bg: var(--gold); }
html[data-label="mastermind"] { --label-bg: var(--accent); }
html[data-label="weekday_warrior"] { --label-bg: var(--green); }
html[data-label="host"] { --label-bg: var(--orange); }
html[data-label="regular"] { --label-bg: var(--red); }
html[data-label="photographer"] { --label-bg: var(--bg-card); }
html[data-label="connector"] { --label-bg: var(--gold); }
html[data-label="decider"] { --label-bg: var(--accent-soft); }
html[data-label="explorer"] { --label-bg: var(--accent-deep); }
html[data-label="reliable"] { --label-bg: var(--green); }
html[data-label="weekender"] { --label-bg: var(--paper); }
html[data-label="planner"] { --label-bg: var(--navy-light); --label-icon: var(--accent-soft); }

html {
    --label-ink: var(--text-bright);
    --label-line: rgba(255, 255, 255, 0.25);
    --label-chip: rgba(255, 255, 255, 0.16);
}
html[data-label="last_minute"], html[data-label="weekday_warrior"], html[data-label="host"],
html[data-label="regular"], html[data-label="connector"], html[data-label="decider"],
html[data-label="reliable"], html[data-label="weekender"] {
    --label-ink: var(--ink-dark);
    --label-line: rgba(28, 20, 0, 0.25);
    --label-chip: rgba(28, 20, 0, 0.14);
}

[hidden] { display: none !important; }

html, body {
    margin: 0;
    height: 100%;
    overflow: hidden;
    background: var(--slide-bg);
    transition: background-color 600ms ease;
}

body {
    font-family: 'montserrat', sans-serif;
    color: var(--text-bright);
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none;
    user-select: none;
}

/* The label's own color arrives as a circle from its icon (.wash), which
   reaches the screen's edges; the page behind it catches up once covered. */
html[data-slide="label"], html[data-slide="label"] body, html[data-slide="label"] .stage {
    transition-delay: 850ms;
}

p, h1 { margin: 0; }

.story {
    position: fixed;
    inset: 0;
    box-sizing: border-box;
    /* In the app's frame env() is zero; the app passes the real insets in. */
    padding: max(env(safe-area-inset-top), var(--safe-top, 0px)) 0 max(env(safe-area-inset-bottom), var(--safe-bottom, 0px));
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    touch-action: manipulation;
}

/* Everything is laid out on a fixed 390x844 stage that is scaled to the
   screen, so the choreography lands in the same place on every phone. It
   doesn't clip: full-bleed things reach past it to the screen's edges
   (--bleed-*, set by fitStage), and .story clips at the screen. */
.stage {
    position: relative;
    flex: none;
    width: 390px;
    height: 844px;
    overflow: visible;
    transform: scale(var(--fit, 1));
    background: var(--slide-bg);
    color: var(--slide-ink);
    transition: background-color 600ms ease, color 400ms ease;
}

.wash {
    --wash-at: calc(99px + var(--bleed-x, 0px)) calc(227px + var(--bleed-top, 0px));
    position: absolute;
    top: calc(var(--bleed-top, 0px) * -1);
    right: calc(var(--bleed-x, 0px) * -1);
    bottom: calc(var(--bleed-bottom, 0px) * -1);
    left: calc(var(--bleed-x, 0px) * -1);
    background: var(--label-bg);
    clip-path: circle(0px at var(--wash-at));
    transition: clip-path 900ms var(--ease-move);
}
html[data-slide="label"] .wash { clip-path: circle(var(--wash-r, 1000px) at var(--wash-at)); }

/* ---------- Actors: pictures that travel from slide to slide ---------- */

/* Its own layer, so an actor's z-index only orders the actors among
   themselves and the slide text always stays on top of the pictures. */
.actors {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

.actor {
    position: absolute;
    left: 0;
    top: 0;
    width: 0;
    height: 0;
    opacity: 0;
    transition:
        left 950ms var(--ease-move),
        top 950ms var(--ease-move),
        width 950ms var(--ease-move),
        height 950ms var(--ease-move),
        border-radius 950ms var(--ease-move),
        transform 950ms var(--ease-move),
        opacity 500ms ease;
    transition-delay: var(--delay, 0ms);
}
.actors.no-move .actor { transition: none; }

.actor .bob {
    width: 100%;
    height: 100%;
    overflow: hidden;
    border-radius: inherit;
    animation: bob var(--bob-time, 4s) ease-in-out var(--bob-delay, 0s) infinite alternate;
}
.actor.is-still .bob { animation: none; }

@keyframes bob {
    from { transform: translateY(-5px); }
    to { transform: translateY(5px); }
}

.person { border-radius: 50%; }
.person .bob, .avatar {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    container-type: inline-size;
    background: var(--avatar-bg);
    color: var(--avatar-ink);
}
.person .bob { box-shadow: 0 0 0 3px var(--slide-bg); }
.person img, .avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.initial { font-size: 38cqi; font-weight: 800; line-height: 1; }

/* Faces without a picture get a color of their own, so they read as
   different people while they move around. */
.tone0 { --avatar-bg: var(--paper); --avatar-ink: var(--ink-dark); }
.tone1 { --avatar-bg: var(--accent-soft); --avatar-ink: var(--ink-dark); }
.tone2 { --avatar-bg: var(--orange); --avatar-ink: var(--ink-dark); }
.tone3 { --avatar-bg: var(--green); --avatar-ink: var(--ink-dark); }
.tone4 { --avatar-bg: var(--gold); --avatar-ink: var(--ink-dark); }
.tone5 { --avatar-bg: var(--red); --avatar-ink: var(--ink-dark); }

.avatar { width: var(--s, 40px); height: var(--s, 40px); flex: none; border-radius: 50%; }

.theme { border-radius: 16px; }
.theme .bob { position: relative; background: var(--bg-card); }
.theme img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.theme .shade { position: absolute; inset: 0; opacity: 0; transition: opacity 700ms ease; }
.theme .shadeBleed { background: var(--shade-bleed); }
.theme .shadeCaption { background: var(--shade-caption); }
.theme.is-bleed .shadeBleed, .theme.is-captioned .shadeCaption { opacity: 1; }

/* A spot on a slide where a traveling face lands. While a face is docked the
   spot itself goes see-through, since the faces sit underneath the text. */
.dock.is-docked { background: transparent !important; }
.dock.is-docked > * { visibility: hidden; }

/* ---------- Slides ---------- */

.slide {
    position: absolute;
    inset: 0;
    z-index: 1;
    visibility: hidden;
    opacity: 0;
    transition: opacity 250ms ease, visibility 0s linear 250ms;
}
.slide.is-active {
    visibility: visible;
    opacity: 1;
    transition: opacity 250ms ease;
}

.slide.is-active [data-rise] {
    animation: rise 750ms var(--ease-move) both;
    animation-delay: calc(var(--d, 0) * 1ms);
}
.slide.is-active [data-pop] {
    animation: pop 800ms var(--ease-pop) both;
    animation-delay: calc(var(--d, 0) * 1ms);
}

@keyframes rise {
    from { opacity: 0; transform: translateY(26px); }
    to { opacity: 1; transform: none; }
}
@keyframes pop {
    from { opacity: 0; transform: scale(0.3) rotate(-14deg); }
    to { opacity: 1; transform: none; }
}

/* Shared pieces */
.blockTop { position: absolute; left: 24px; right: 24px; top: 72px; }
.h1Big { font-size: 38px; line-height: 42px; font-weight: 900; letter-spacing: -1px; }
.h1Huge { font-size: 44px; line-height: 48px; font-weight: 900; letter-spacing: -1px; }
.sub { margin-top: 10px; font-size: 16px; line-height: 23px; font-weight: 500; color: var(--soft-ink); }
.sub:empty { display: none; }
.kicker { font-size: 17px; line-height: 22px; font-weight: 700; color: var(--accent-soft); }
.kickerPlain { font-size: 19px; line-height: 25px; font-weight: 700; }
.sectionLabel { margin-bottom: 6px; font-size: 14px; line-height: 20px; font-weight: 700; color: var(--soft-ink); }

.tileGrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.tile { box-sizing: border-box; padding: 14px; border-radius: 14px; background: var(--tile-bg); }
.tileValue { font-size: 30px; line-height: 34px; font-weight: 900; letter-spacing: -0.5px; overflow-wrap: anywhere; }
.tileLabel { margin-top: 3px; font-size: 14px; line-height: 20px; font-weight: 500; color: var(--soft-ink); }
.tileNote { margin-top: 2px; font-size: 13px; line-height: 18px; font-weight: 600; color: var(--soft-ink); }
.infoTile { padding: 13px 14px; }
.infoLabel { font-size: 13px; line-height: 17px; color: var(--soft-ink); }
.infoValue { margin-top: 3px; font-size: 17px; line-height: 22px; font-weight: 800; }
.bottomTiles { position: absolute; left: 24px; right: 24px; bottom: 40px; }

.line {
    min-height: 48px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border-top: 1px solid var(--line);
}
.lineLabel { font-size: 15px; line-height: 20px; font-weight: 500; color: var(--soft-ink); }
.lineValue { font-size: 16px; line-height: 20px; font-weight: 800; text-align: right; }

.chip { padding: 8px 14px; border-radius: 20px; background: var(--tile-bg); font-size: 14px; font-weight: 700; }

.pips { display: flex; flex-wrap: wrap; gap: 6px; }
.pip { width: 22px; height: 22px; border-radius: 6px; background: var(--tile-bg); }
.pip.is-on { background: var(--accent-soft); }

/* 01 Intro */
.introText { position: absolute; left: 24px; right: 24px; top: 500px; }
.introYear { font-size: 112px; line-height: 108px; font-weight: 900; letter-spacing: -5px; }
.introTitle { margin-top: 6px; font-size: 26px; line-height: 32px; font-weight: 800; }
.introSub { margin-top: 10px; font-size: 16px; line-height: 23px; font-weight: 500; color: var(--soft-ink); }
.tapHint { position: absolute; left: 0; right: 0; bottom: 36px; text-align: center; font-size: 14px; font-weight: 700; color: var(--text-secondary); }

/* 02 Plans */
.plansTop { position: absolute; left: 24px; right: 24px; top: 92px; }
.plansKicker { font-size: 24px; line-height: 30px; font-weight: 700; }
.bigCount { margin: 2px 0 0 -6px; font-size: 156px; line-height: 150px; font-weight: 900; letter-spacing: -8px; font-variant-numeric: tabular-nums; }
.plansUnit { font-size: 30px; line-height: 34px; font-weight: 800; }
.plansSub { margin-top: 12px; font-size: 17px; line-height: 24px; font-weight: 600; }
.facepileLabel { position: absolute; top: 459px; font-size: 17px; line-height: 22px; font-weight: 700; }
.split { position: absolute; left: 24px; right: 24px; top: 528px; }
.splitBar { height: 14px; border-radius: 7px; overflow: hidden; background: var(--split-track); }
.splitHosted {
    display: block;
    width: 0;
    height: 100%;
    border-radius: 7px;
    background: var(--text-bright);
    transition: width 1100ms var(--ease-move);
}
.slide.is-active .splitHosted { width: var(--share, 0%); transition-delay: 1600ms; }
.splitLegend { display: flex; justify-content: space-between; margin-top: 10px; font-size: 15px; font-weight: 700; }
.plansTiles { position: absolute; left: 24px; right: 24px; top: 528px; }

/* 03 Your calendar */
.calTop { position: absolute; left: 24px; right: 24px; top: 72px; }
.calMonths { margin-top: 22px; display: flex; flex-direction: column; gap: 6px; }
.calMonth { display: flex; align-items: center; gap: 6px; height: 12px; }
.calMonthLabel { width: 12px; font-size: 10.5px; font-weight: 700; color: var(--text-secondary); }
.calDays { display: flex; gap: 2.5px; }
.calDot { width: 8px; height: 8px; border-radius: 50%; background: var(--dot-off); }
.calDot.is-on { background: var(--accent-soft); }
.slide.is-active .calDot.is-on { animation: pop 500ms var(--ease-pop) both; animation-delay: calc(var(--d, 0) * 1ms + 350ms); }
.calWeek { margin-top: 22px; display: flex; align-items: flex-end; gap: 8px; height: 104px; }
.calBar { flex: 1; height: 104px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 5px; }
.calBarN, .calBarLabel { font-size: 12px; line-height: 14px; font-weight: 700; color: var(--text-secondary); }
.calBarLabel { font-size: 11px; }
.calBar.is-top .calBarN, .calBar.is-top .calBarLabel { color: var(--text-bright); }
.calBarFill {
    width: 100%;
    height: 0;
    border-radius: 4px 4px 0 0;
    background: var(--bg-chip);
    transition: height 900ms var(--ease-move);
}
.calBar.is-top .calBarFill { background: var(--accent-soft); }
.slide.is-active .calBarFill { height: var(--h); transition-delay: calc(var(--i) * 70ms + 1300ms); }
.calTiles { position: absolute; left: 24px; right: 24px; bottom: 34px; }

/* 04 Top theme */
.themeKicker { position: absolute; left: 24px; right: 80px; top: 96px; font-size: 19px; line-height: 25px; font-weight: 700; }
.themeMain { position: absolute; left: 24px; right: 24px; top: 452px; }
.themeName { font-size: 64px; line-height: 66px; font-weight: 900; letter-spacing: -2px; }
.themeCount { margin-top: 6px; font-size: 21px; line-height: 26px; font-weight: 700; }
.themeCaption { position: absolute; top: 696px; width: 141px; }
.themeCaption1 { left: 36px; }
.themeCaption2 { left: 213px; }
.themeCaptionName { font-size: 15px; line-height: 19px; font-weight: 800; }
.themeCaptionCount { margin-top: 2px; font-size: 13px; line-height: 17px; font-weight: 600; color: var(--text-soft); }
.themeGrid { position: absolute; left: 24px; right: 24px; top: 420px; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px 10px; }
.themeTile img { display: block; width: 100%; aspect-ratio: 1; border-radius: 12px; object-fit: cover; filter: grayscale(1) brightness(0.55); }
.themeTileName { margin-top: 6px; font-size: 12px; line-height: 15px; font-weight: 700; color: var(--text-secondary); }

/* 05 Places */
.placeName { margin-top: 8px; font-size: 54px; line-height: 56px; font-weight: 900; letter-spacing: -1.5px; }
.placeCount { margin-top: 8px; font-size: 21px; line-height: 26px; font-weight: 700; }
.placeFrame {
    position: absolute;
    left: 24px;
    top: 298px;
    width: 342px;
    height: 220px;
    border-radius: 14px;
    background: var(--tile-bg);
    display: flex;
    align-items: center;
    justify-content: center;
}
.placeFrame svg { width: 64px; height: 64px; opacity: 0.5; }
.placeList { position: absolute; left: 24px; right: 24px; top: 538px; }
.placeRow { height: 52px; display: flex; align-items: center; gap: 14px; border-bottom: 1px solid var(--line); }
.placeRank { width: 22px; font-size: 16px; font-weight: 900; }
.placeRowName { flex: 1; font-size: 17px; font-weight: 700; }
.placeRowCount { font-size: 16px; font-weight: 800; }
.placeTotal { position: absolute; left: 24px; right: 24px; bottom: 40px; font-size: 17px; line-height: 22px; font-weight: 700; }
.placeChips { position: absolute; left: 24px; right: 24px; top: 300px; display: flex; flex-wrap: wrap; gap: 10px; }
.placeChips .chip { padding: 10px 16px; font-size: 17px; }
.mysteryPin { position: absolute; left: 95px; top: 380px; width: 200px; height: 200px; }
.mysteryPin svg { width: 100%; height: 100%; }
.mysteryPin span { position: absolute; left: 0; right: 0; top: 46px; text-align: center; font-size: 72px; line-height: 72px; font-weight: 900; }

/* 06 Your people */
/* The crew: everyone the same size, rows centred (2, 3, 2+2, 3+2, 3+3). */
.crew { position: absolute; left: 24px; right: 24px; top: 236px; display: flex; flex-wrap: wrap; justify-content: center; row-gap: 22px; }
.crew[data-n="2"], .crew[data-n="3"] { top: 280px; }
.crewMember { width: 114px; display: flex; flex-direction: column; align-items: center; text-align: center; }
.crew[data-n="2"] .crewMember, .crew[data-n="4"] .crewMember { width: 150px; }
.crewFace { --s: 84px; width: var(--s); height: var(--s); flex: none; border-radius: 50%; background: var(--bg-chip); }
.crew[data-n="2"] .crewFace { --s: 116px; }
.crew[data-n="3"] .crewFace { --s: 96px; }
.crewName { margin-top: 10px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 16px; line-height: 20px; font-weight: 800; }
.crewCount { margin-top: 2px; font-size: 14px; line-height: 18px; font-weight: 600; color: var(--soft-ink); }
.crewCount:empty { display: none; }
.crowd { position: absolute; left: 24px; right: 24px; top: 240px; display: grid; grid-template-columns: repeat(4, 64px); justify-content: space-between; row-gap: 16px; }
.crowd .avatar { --s: 64px; }
.crowdMore { position: absolute; left: 24px; top: 488px; font-size: 16px; font-weight: 700; color: var(--soft-ink); }
.aloneText { position: absolute; left: 24px; right: 24px; top: 340px; }
.aloneBtn { margin-top: 26px; padding: 0 22px; }

/* 07 Invites */
.ringBlock { position: absolute; left: 24px; top: 250px; display: flex; align-items: center; gap: 22px; }
.ring { width: 150px; height: 150px; transform: rotate(-90deg); }
.ringTrack { fill: none; stroke: var(--tile-bg); stroke-width: 12; }
.ringFill {
    fill: none;
    stroke: var(--accent-soft);
    stroke-width: 12;
    stroke-linecap: round;
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
    transition: stroke-dashoffset 1400ms var(--ease-move);
}
.slide.is-active .ringFill { stroke-dashoffset: var(--offset, 100); transition-delay: 700ms; }
.ringPct { font-size: 56px; line-height: 58px; font-weight: 900; letter-spacing: -2px; }
.ringLabel { font-size: 18px; font-weight: 700; color: var(--soft-ink); }
.ringCaption { position: absolute; left: 24px; right: 24px; top: 418px; font-size: 16px; line-height: 23px; font-weight: 600; color: var(--soft-ink); }
.pipBlock { position: absolute; left: 24px; right: 24px; top: 280px; }
.slide.is-active .pip { animation: pop 500ms var(--ease-pop) both; animation-delay: calc(var(--d, 0) * 1ms); }
.pipCaption { margin-top: 14px; font-size: 17px; line-height: 22px; font-weight: 700; }
.askerTiles { position: absolute; left: 24px; right: 24px; top: 200px; }
.faceRow { position: absolute; left: 24px; right: 24px; display: flex; align-items: center; gap: 14px; }
.slide[data-v="yes"] .faceRow { top: 480px; }
.slide[data-v="hard"] .faceRow { top: 430px; }
.slide[data-v="asker"] .faceRow { top: 340px; }
.faceDock { width: 56px; height: 56px; flex: none; border-radius: 50%; background: var(--bg-chip); display: flex; align-items: center; justify-content: center; container-type: inline-size; }
.faceLabel { font-size: 14px; line-height: 19px; font-weight: 500; color: var(--soft-ink); }
.faceValue { margin-top: 2px; font-size: 18px; line-height: 23px; font-weight: 800; }
.sentTile { position: absolute; left: 24px; right: 24px; bottom: 40px; }

/* 08 Polls */
.pollPips { margin-top: 18px; gap: 5px; }
.pollPips .pip { width: 12px; height: 12px; border-radius: 3px; }
.pollPips .pip.is-on { background: var(--gold); }
.debate { margin-top: 20px; padding: 16px; }
.debateLabel { font-size: 13px; line-height: 17px; font-weight: 600; color: var(--soft-ink); }
.debateTitle { margin-top: 2px; font-size: 18px; line-height: 22px; font-weight: 800; }
.bars { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.bar { position: relative; height: 32px; display: flex; align-items: center; justify-content: space-between; padding: 0 12px; border-radius: 8px; overflow: hidden; background: var(--divider-soft); }
.barFill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: var(--bar-other); transition: width 1000ms var(--ease-move); }
.bar.is-win .barFill { background: var(--gold); }
.bar.is-win { color: var(--ink-dark); }
.slide.is-active .barFill { width: var(--w); transition-delay: calc(var(--i) * 120ms + 1400ms); }
.barName, .barVotes { position: relative; font-size: 14px; font-weight: 700; }
.debateMeta { margin-top: 10px; font-size: 13px; line-height: 18px; font-weight: 500; color: var(--soft-ink); }
.gotAway { position: absolute; left: 24px; right: 24px; bottom: 40px; }
.gotAway .line { min-height: 40px; }
.slide[data-v="none"] .gotAway { top: 96px; bottom: auto; }
.slide[data-v="none"] .gotAway .sectionLabel { margin-bottom: 18px; font-size: 38px; line-height: 42px; font-weight: 900; letter-spacing: -1px; color: inherit; }

/* 09 Chat */
.chatTop { position: absolute; left: 24px; right: 24px; top: 72px; }
.chatCount { margin: 6px 0 0 -3px; font-size: 96px; line-height: 100px; font-weight: 900; letter-spacing: -4px; font-variant-numeric: tabular-nums; }
.chatUnit { font-size: 25px; line-height: 30px; font-weight: 800; }
.bubbles { position: absolute; left: 24px; right: 24px; top: 300px; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.slide[data-v="quiet"] .bubbles { top: 330px; }
.bubble { max-width: 280px; padding: 12px 16px; border-radius: 18px 18px 18px 4px; background: var(--accent-deep); font-size: 16px; line-height: 21px; font-weight: 600; transform-origin: left bottom; }
.bubble.is-mine { align-self: flex-end; border-radius: 18px 18px 4px 18px; background: var(--text-bright); color: var(--accent-deep); font-weight: 700; transform-origin: right bottom; }
.reactBox { position: absolute; left: 24px; right: 24px; bottom: 40px; padding: 18px; }
.reactTitle { margin-bottom: 14px; font-size: 16px; font-weight: 800; }
.reactGrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px 8px; }
.reaction { display: flex; align-items: center; gap: 8px; }
.reactionEmoji { font-size: 26px; line-height: 30px; }
.reactionN { font-size: 17px; font-weight: 800; }

/* 10 Photos */
.prints { position: absolute; left: 0; right: 0; top: 270px; height: 300px; }
.print {
    position: absolute;
    box-sizing: border-box;
    width: 150px;
    padding: 8px 8px 26px;
    border-radius: 4px;
    background: var(--print-paper);
    box-shadow: var(--print-shadow);
    transform: rotate(var(--rot, 0deg));
}
.printPhoto { aspect-ratio: 1; overflow: hidden; background: var(--print-empty); }
.printPhoto img { display: block; width: 100%; height: 100%; object-fit: cover; }
.print.is-empty .printPhoto img { display: none; }
.slide.is-active .print { animation: throwIn 850ms var(--ease-pop) both; animation-delay: calc(var(--d, 0) * 1ms); }
@keyframes throwIn {
    from { opacity: 0; transform: translate(var(--fx, 0px), 360px) rotate(calc(var(--rot, 0deg) * -3)) scale(1.15); }
    to { opacity: 1; transform: rotate(var(--rot, 0deg)); }
}
.photoBottom { position: absolute; left: 24px; right: 24px; bottom: 40px; display: flex; flex-direction: column; gap: 10px; }
.filmTipTitle { font-size: 17px; line-height: 22px; font-weight: 800; }

/* 11 Your label */
.labelIcon { color: var(--label-icon, var(--label-ink)); }
.labelIcon svg { display: block; width: 100%; height: 100%; }
.labelKicker { position: absolute; left: 24px; top: 96px; font-size: 21px; line-height: 26px; font-weight: 700; }
.labelIconBig { position: absolute; left: 24px; top: 152px; width: 150px; height: 150px; }
.labelText { position: absolute; left: 24px; right: 24px; top: 338px; }
.labelName { font-size: 68px; line-height: 68px; font-weight: 900; letter-spacing: -2.5px; }
.labelLine { margin-top: 14px; font-size: 18px; line-height: 26px; font-weight: 600; }
.labelBottom { position: absolute; left: 24px; right: 24px; bottom: 40px; display: flex; flex-direction: column; gap: 14px; }
.labelBottom .lineLabel { font-weight: 600; }
.labelBottom .lineValue { font-size: 19px; font-weight: 900; }
.alsoTitle { margin-bottom: 8px; font-size: 14px; font-weight: 600; }
.alsoChips { display: flex; flex-wrap: wrap; gap: 8px; }

/* 12 Share card. Only your own numbers: no friends, places or photos, so
   sharing it never shows anyone else. */
.card {
    position: absolute;
    left: 24px;
    top: 76px;
    width: 342px;
    height: 560px;
    border-radius: 20px;
    overflow: hidden;
    background: var(--navy-light);
    color: var(--text-bright);
}
.slide.is-active .card { animation: cardIn 950ms var(--ease-pop) 150ms both; }
@keyframes cardIn {
    from { opacity: 0; transform: translateY(140px) rotate(-6deg) scale(0.9); }
    to { opacity: 1; transform: none; }
}
.cardBand { position: relative; height: 262px; background: var(--label-bg); color: var(--label-ink); }
.cardYear { position: absolute; left: 20px; top: 16px; font-size: 40px; line-height: 44px; font-weight: 900; letter-spacing: -1.5px; }
.cardLogo { position: absolute; right: 16px; top: 16px; width: 44px; height: 44px; border-radius: 11px; }
.cardIcon { position: absolute; left: 18px; top: 78px; width: 64px; height: 64px; }
.cardWho { position: absolute; left: 20px; right: 20px; top: 164px; }
.cardWas { font-size: 14px; line-height: 18px; font-weight: 700; }
.cardLabel { margin-top: 2px; font-size: 38px; line-height: 42px; font-weight: 900; letter-spacing: -1.5px; }
.cardStats {
    position: absolute;
    left: 20px;
    right: 20px;
    top: 290px;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px 12px;
}
.cardStatValue { font-size: 28px; line-height: 32px; font-weight: 900; letter-spacing: -1px; }
.cardStat.isWord .cardStatValue { font-size: 22px; }
.cardStatLabel { margin-top: 1px; font-size: 14px; line-height: 18px; font-weight: 600; }
.cardSite { position: absolute; left: 20px; bottom: 16px; font-size: 13px; font-weight: 600; }

.shareActions { position: absolute; left: 24px; right: 24px; bottom: 24px; display: flex; flex-direction: column; gap: 10px; }
.shareButtons { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.btn {
    height: 52px;
    border: 0;
    border-radius: 10px;
    font: inherit;
    font-size: 16px;
    font-weight: 700;
    color: var(--text-bright);
}
.btnPrimary { background: var(--accent); }
.btnQuiet { background: var(--bg-card); }

/* A quiet year */
/* Reaches the screen's top and side edges; its fade ends where it always did. */
.quietArt {
    position: absolute;
    left: calc(var(--bleed-x, 0px) * -1);
    top: calc(var(--bleed-top, 0px) * -1);
    width: calc(390px + var(--bleed-x, 0px) * 2);
    height: calc(390px + var(--bleed-top, 0px));
    overflow: hidden;
    /* The last few pixels fade into the page (the shade's own end color), so
       the picture can't peek out as a line under it. */
    -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 6px), transparent);
    mask-image: linear-gradient(180deg, #000 calc(100% - 6px), transparent);
}
.quietArt img { display: block; width: 100%; height: 100%; object-fit: cover; }
.quietArt::after { content: ''; position: absolute; inset: 0; background: var(--shade-quiet); }
.slide.is-active .quietArt img { animation: drift 12s ease-out both; }
@keyframes drift {
    from { transform: scale(1.18); }
    to { transform: scale(1); }
}
.quietText { position: absolute; left: 24px; right: 24px; top: 300px; }
.quietTitle { margin-top: 8px; }
.quietRows { margin-top: 30px; display: flex; flex-direction: column; gap: 10px; }
.quietRows .line { min-height: 0; padding: 15px; border: 0; border-radius: 10px; background: var(--bg-card); }
.quietBtn { position: absolute; left: 24px; right: 24px; bottom: 36px; }
.story.is-quiet .progress { display: none; }

/* ---------- Chrome ---------- */

.progress { position: absolute; left: 12px; right: 12px; top: 14px; z-index: 2; display: flex; gap: 4px; }
.segment { position: relative; flex: 1; height: 3px; border-radius: 2px; overflow: hidden; }
.segment::before { content: ''; position: absolute; inset: 0; background: currentColor; opacity: 0.3; }
.segmentFill { position: absolute; inset: 0; background: currentColor; transform: scaleX(0); transform-origin: left; }
.segment.is-past .segmentFill { transform: scaleX(1); }
.segment.is-current .segmentFill { animation: segmentFill var(--ms, 5000ms) linear forwards; }
html.is-paused .segment.is-current .segmentFill { animation-play-state: paused; }
@keyframes segmentFill { to { transform: scaleX(1); } }

.closeBtn {
    position: absolute;
    top: 24px;
    right: 8px;
    z-index: 2;
    width: 44px;
    height: 44px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: none;
    color: inherit;
}

.toast {
    position: fixed;
    left: 50%;
    bottom: calc(24px + max(env(safe-area-inset-bottom), var(--safe-bottom, 0px)));
    max-width: 320px;
    padding: 12px 16px;
    border-radius: 10px;
    background: var(--bg-card);
    color: var(--text-bright);
    font-size: 14px;
    line-height: 20px;
    font-weight: 600;
    text-align: center;
    opacity: 0;
    transform: translate(-50%, 20px);
    transition: opacity 250ms ease, transform 250ms ease;
    pointer-events: none;
}
.toast.is-shown { opacity: 1; transform: translate(-50%, 0); }

/* In the app there is one button: its share sheet also saves the image. */
.shareButtons.isSingle { grid-template-columns: minmax(0, 1fr); }

/* Someone on the invites slide who isn't one of the travelling faces. */
.faceDock { position: relative; overflow: hidden; }
.faceDock img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Until the app has handed over the review: a quiet pulse, no story yet. */
.story.is-loading .stage::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: 44px;
    height: 44px;
    margin: -22px 0 0 -22px;
    border-radius: 12px;
    background: var(--bg-card);
    animation: loadingPulse 1.2s ease-in-out infinite;
}
@keyframes loadingPulse {
    0%, 100% { opacity: 0.35; transform: scale(0.9); }
    50% { opacity: 1; transform: scale(1); }
}

/* Instead of the story: "open it in the app", or "it didn't load". */
.notice {
    position: absolute;
    inset: 0;
    z-index: 1;
    box-sizing: border-box;
    padding: 0 32px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 14px;
}
.noticeLogo { width: 64px; height: 64px; margin-bottom: 10px; border-radius: 16px; }
.noticeLink { margin-top: 18px; display: flex; align-items: center; justify-content: center; text-decoration: none; }
.notice[data-kind="error"] .noticeLink { display: none; }

/* Reduced motion: pictures fade into place instead of flying there. */
@media (prefers-reduced-motion: reduce) {
    .actor { transition: opacity 300ms ease; }
    .actor .bob { animation: none; }
    .wash { transition: none; }
    .slide.is-active [data-rise], .slide.is-active [data-pop], .slide.is-active .card,
    .slide.is-active .print, .slide.is-active .pip, .slide.is-active .calDot.is-on { animation-name: fadeIn; }
    @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
}
