/* =========================================================
   Tokens — pulled from slide-themes.md + DESIGN.md
   ========================================================= */
:root {
    /* Colors */
    --color-primary: #3f7d20;
    --color-secondary: #7db405;
    --color-navy: #1a3a8c;
    --color-dark: #0d0a0b;
    --color-med-gray: #565556;
    --color-light-gray: #b8b8b8;
    --color-page-bg: #ffffff;
    --color-moment-bg: #e0e0e2;
    --color-on-dark: #ffffff;

    --font-sans: "Poppins", system-ui, sans-serif;

    /* Type scale (cqw scales with stage width) */
    --fs-page-title: 4.2cqw;
    --fs-eyebrow: 1.2cqw;
    --fs-headline: 3.6cqw;
    --fs-body: 1.6cqw;
    --fs-citation: 1cqw;
    --fs-list-number: 4cqw;
    --fs-list-item-title: 1.85cqw;
    --fs-list-item-body: 1.6cqw;
    --fs-moment-headline: 6.8cqw;
    --fs-moment-quote: 4.2cqw;
    --fs-footer-label: 1cqw;
    --fs-caption: 1cqw;

    /* Radii */
    --r-sm: 0.5cqw;
    --r-md: 1cqw;
    --r-lg: 1.5cqw;
    --r-card: 1.2cqw;
    --r-pill: 999px;

    /* Spacing scale — from DESIGN.md (8 / 16 / 24 / 48 / 80 / 140px on a
       1140px portfolio container). Here we express in cqw of a 1919-wide
       stage so the visual rhythm matches the portfolio site. */
    --s-xs: 0.42cqw; /* ≈ 8px */
    --s-sm: 0.83cqw; /* ≈ 16px */
    --s-md: 1.25cqw; /* ≈ 24px */
    --s-lg: 2.5cqw; /* ≈ 48px */
    --s-xl: 4.17cqw; /* ≈ 80px */
    --s-xxl: 7.3cqw; /* ≈ 140px */
    --s-edge: 4.17cqw; /* edge margin = xl */

    /* Animation */
    --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
    --dur-fast: 240ms;
    --dur: 480ms;
    --dur-slow: 720ms;

    /* Drop shadows — use as filter: var(--shadow-md). Tiers go sm/md/lg. */
    --shadow-sm: drop-shadow(0 0.4cqw 0.6cqw rgba(15, 23, 42, 0.12));
    --shadow-md: drop-shadow(0 1.2cqw 1.6cqw rgba(15, 23, 42, 0.18));
    --shadow-lg: drop-shadow(0 2cqw 2.8cqw rgba(15, 23, 42, 0.22));
}

/* =========================================================
   Base
   ========================================================= */
*,
*::before,
*::after {
    box-sizing: border-box;
}
html,
body {
    margin: 0;
    height: 100%;
    background: var(--color-page-bg);
    color: var(--color-dark);
    font-family: var(--font-sans);
    font-size: 18px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    overflow: hidden;
}
img {
    max-width: 100%;
    display: block;
}
button {
    font: inherit;
    cursor: pointer;
}

/* =========================================================
   Stage — every slide is a 16:9 box. Container query units (cqw, cqh)
   reference the stage's own size so type scales smoothly.
   ========================================================= */
.deck {
    position: relative;
    height: 100vh;
    width: 100vw;
    background: var(--color-page-bg);
}

.slide {
    position: fixed;
    inset: 0;
    display: grid;
    place-items: center;
    background: var(--color-page-bg);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur) ease;
    overflow: hidden;
}
.slide.is-active {
    opacity: 1;
    pointer-events: auto;
}

.stage {
    position: relative;
    width: min(100vw, calc(100vh * 16 / 9));
    aspect-ratio: 16 / 9;
    background: var(--color-page-bg);
    overflow: hidden;
    container-type: inline-size;
}

/* Direct children of stage are absolutely positioned. Images carry inline
   styles for slide-relative coords; .t-text is positioned per-template. */
.stage > * {
    position: absolute;
    margin: 0;
}
.stage > img {
    object-fit: contain;
}

/* =========================================================
   Phone-frame composition
   ========================================================= */
.phone-screen-clip {
    position: absolute;
    overflow: hidden;
    border-radius: 9% / 4.4%;
}
.phone-screen-clip > img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top;
}
.phone-frame {
    pointer-events: none;
}

/* =========================================================
   Template: comparison-phones
   ========================================================= */
.slide[data-template="comparison-phones"] .stage {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: stretch;
    padding: var(--s-xl);
    gap: var(--s-md);
}
.slide[data-template="comparison-phones"] .t-text {
    position: static;
    inset: auto;
    width: 100%;
    max-width: 38cqw;
    align-self: flex-start;
}
.slide[data-template="comparison-phones"][data-has-text="false"] .t-text {
    display: none;
}
/* Phone row: flex layout. Each child is a .phone-col (figure + caption).
   Phones use explicit cqw-based height (cqh isn't reliable because the
   stage uses container-type: inline-size). */
.slide[data-template="comparison-phones"] .phone-row {
    position: static;
    inset: auto;
    display: flex;
    justify-content: center;
    align-items: flex-end;
    gap: var(--s-xl);
}
.slide[data-template="comparison-phones"] .phone-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s-xs);
    flex: 0 0 auto;
}
.slide[data-template="comparison-phones"] .phone-col > .phone {
    position: relative;
    height: 45cqw; /* ~80% of slide height (16:9 = 56.25cqw tall) */
    aspect-ratio: 0.485; /* width derives from height */
    flex: 0 0 auto;
}
/* When a left text column is present, give the phones a bit less height. */
.slide[data-template="comparison-phones"][data-has-text="true"]
    .phone-col
    > .phone {
    height: 42cqw;
}
.slide[data-template="comparison-phones"] .phone-row .phone-screen {
    position: absolute;
    inset: 1.5% 3.5%;
    border-radius: 9% / 4.4%;
    overflow: hidden;
    background: #efefef;
}
.slide[data-template="comparison-phones"] .phone-row .phone-screen > img,
.slide[data-template="comparison-phones"] .phone-row .phone-screen > video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top;
}
.slide[data-template="comparison-phones"] .phone-row .phone-frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}
.slide[data-template="comparison-phones"] .phone-caption {
    margin: 0;
    font-size: var(--fs-caption);
    font-weight: 400;
    color: var(--color-med-gray);
    text-align: center;
    line-height: 1.3;
}
.slide[data-template="comparison-phones"][data-has-text="true"] .stage {
    flex-direction: row;
    align-items: center;
}
.slide[data-template="comparison-phones"][data-has-text="true"] .phone-row {
    flex: 1 1 auto;
}

/* =========================================================
   .t-text — the text container that templates position via CSS.
   By default, children stack vertically with NO gap; each slot defines
   its own bottom margin per the spacing scale.
   ========================================================= */
.t-text {
    position: absolute;
    display: flex;
    flex-direction: column;
}

/* Slot typography (template-agnostic defaults; templates override positioning) */
.t-text > .page-title {
    font-size: var(--fs-page-title);
    font-weight: 700;
    color: var(--color-dark);
    line-height: 1.05;
    letter-spacing: -0.01em;
    margin: 0 0 var(--s-md);
}
.t-text > .eyebrow {
    font-size: var(--fs-eyebrow);
    font-weight: 400;
    color: var(--color-med-gray);
    line-height: 1.2;
    margin: 0 0 var(--s-xs); /* tight: eyebrow → headline */
    text-transform: uppercase;
}
.t-text > .headline {
    font-size: var(--fs-headline);
    font-weight: 700;
    color: var(--color-secondary);
    line-height: 1.05;
    letter-spacing: -0.01em;
    margin: 0 0 var(--s-md); /* headline → body */
}
.t-text > .lead {
    font-size: var(--fs-headline);
    font-weight: 700;
    color: var(--color-secondary);
    line-height: 1.05;
    letter-spacing: -0.01em;
    margin: 0 0 var(--s-md);
}
.t-text > .body {
    font-size: var(--fs-body);
    font-weight: 400;
    color: var(--color-dark);
    line-height: 1.45;
    margin: 0 0 var(--s-sm);
}
.t-text > .body-list {
    list-style: decimal;
    padding-left: 1.5em;
    margin: 0 0 var(--s-md);
    font-size: var(--fs-body);
    font-weight: 400;
    color: var(--color-dark);
    line-height: 1.45;
}
.t-text > .body-list > li {
    margin: 0 0 var(--s-sm);
}
.t-text > .body-list > li::marker {
    color: var(--color-primary);
    font-weight: 700;
}
.t-text .hl {
    color: var(--color-primary);
    font-weight: 700;
}
.slide[data-template="project-grid"] .grid-eyebrow {
    position: absolute;
    left: var(--s-lg);
    top: var(--s-lg);
    font-size: var(--fs-eyebrow);
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-secondary);
    margin: 0;
    z-index: 10;
}
.t-text > .citation {
    font-size: var(--fs-citation);
    font-weight: 400;
    font-style: italic;
    color: var(--color-light-gray);
    line-height: 1.4;
    margin: var(--s-md) 0 0;
}
.t-text > .moment-headline {
    font-size: var(--fs-moment-headline);
    font-weight: 700;
    color: var(--color-dark);
    line-height: 1;
    letter-spacing: -0.02em;
    margin: 0;
}
.t-text > .moment-quote {
    font-size: var(--fs-moment-quote);
    font-weight: 700;
    color: var(--color-navy);
    line-height: 1.1;
    letter-spacing: -0.01em;
    margin: 0;
}
.t-text > .attrib-name {
    font-size: var(--fs-body);
    font-weight: 400;
    color: var(--color-med-gray);
    margin: 0 0 var(--s-md);
}
.footer-label {
    /* Stays absolutely positioned outside .t-text */
    position: absolute;
    left: var(--s-edge);
    bottom: var(--s-edge);
    font-size: var(--fs-footer-label);
    color: var(--color-light-gray);
    margin: 0;
    z-index: 50;
}

/* =========================================================
   Numbered lists (used by agenda + numbered-list templates)
   ========================================================= */
.t-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s-lg) var(--s-xl);
}
.t-list--single {
    grid-template-columns: 1fr;
    gap: var(--s-md);
}
.t-list > li {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--s-md);
    align-items: start;
}
.list-num {
    font-size: var(--fs-list-number);
    font-weight: 300;
    color: var(--color-light-gray);
    line-height: 1;
    min-width: 2ch;
}
.list-title {
    font-size: var(--fs-list-item-title);
    font-weight: 700;
    color: var(--color-secondary);
    line-height: 1.2;
    margin: 0;
}
.list-content > .list-title {
    margin-bottom: var(--s-xs);
}
.list-body {
    font-size: var(--fs-list-item-body);
    font-weight: 400;
    color: var(--color-dark);
    line-height: 1.4;
    margin: 0;
}

/* =========================================================
   Authored-position text (for freeform templates: timeline, image-hero,
   project-grid). Each .tb has slot typography but inline positioning.
   ========================================================= */
.tb {
    font-family: var(--font-sans);
    margin: 0;
    line-height: 1.2;
}
.tb--page-title {
    font-size: var(--fs-page-title);
    font-weight: 700;
    color: var(--color-dark);
    line-height: 1.05;
    letter-spacing: -0.01em;
}
.tb--caption {
    font-size: var(--fs-caption);
    font-weight: 400;
    color: var(--color-med-gray);
    line-height: 1.3;
}
.tb--year {
    font-size: var(--fs-citation);
    font-weight: 700;
    letter-spacing: 0.1em;
    color: var(--color-med-gray);
}
.tb--section-label {
    font-size: var(--fs-citation);
    color: var(--color-light-gray);
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
.timeline-logo {
    position: absolute;
    width: auto;
    object-fit: contain;
    object-position: left center;
}
.tb--body {
    font-size: var(--fs-body);
    color: var(--color-dark);
}

/* =========================================================
   TEMPLATE: opening
   ========================================================= */
.slide[data-template="opening"] .stage {
    background: var(--color-moment-bg);
}
.slide[data-template="opening"] .opening-photo {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 32%;
    height: 100%;
    object-fit: contain;
    object-position: bottom left;
}
.slide[data-template="opening"] .t-text {
    left: 38%;
    top: 0;
    bottom: 0;
    right: var(--s-edge);
    justify-content: center;
}

/* =========================================================
   TEMPLATE: agenda
   Page title top-left, list below
   ========================================================= */
.slide[data-template="agenda"] .t-text {
    left: var(--s-edge);
    top: var(--s-edge);
    right: var(--s-edge);
    bottom: var(--s-edge);
}
.slide[data-template="agenda"] .t-text > .page-title {
    margin-bottom: var(--s-xl);
}

/* =========================================================
   TEMPLATE: section-cover
   Image at left ~38%, text right anchored top ~22%
   ========================================================= */
.slide[data-template="section-cover"] .cover-photo {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 38%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}
.slide[data-template="section-cover"] .t-text {
    left: 42%;
    top: 22%;
    width: 50%;
}
/* Tighter eyebrow→headline rhythm on covers */
.slide[data-template="section-cover"] .t-text > .eyebrow {
    margin-bottom: var(--s-xs);
}
.slide[data-template="section-cover"] .t-text > .headline {
    margin-bottom: var(--s-md);
}
/* =========================================================
   TEMPLATE: section-overview
   Photo left ~38%, numbered list right. Hybrid of section-cover + numbered-list.
   ========================================================= */
.slide[data-template="section-overview"] .cover-photo {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 38%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}
.slide[data-template="section-overview"] .t-text {
    left: 42%;
    top: var(--s-edge);
    bottom: var(--s-edge);
    width: 54%;
    overflow-y: auto;
}
.slide[data-template="section-overview"] .t-text > .page-title {
    margin-bottom: var(--s-md);
}
.slide[data-template="section-overview"] .t-list {
    gap: var(--s-sm);
}
.slide[data-template="section-overview"] .list-num {
    font-size: 2.5cqw;
}
.slide[data-template="section-overview"] .list-title {
    font-size: 1.4cqw;
}
.slide[data-template="section-overview"] .list-body {
    font-size: 1.1cqw;
}

.cover-themes {
    list-style: none;
    margin: var(--s-md) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--s-xs);
    align-items: flex-start;
}
.cover-themes li {
    font-size: var(--fs-caption);
    font-weight: 500;
    color: var(--color-med-gray);
    background: rgba(0, 0, 0, 0.05);
    padding: 0.3cqw 0.8cqw;
    border-radius: var(--r-pill);
    line-height: 1.4;
}

/* =========================================================
   TEMPLATE: bio-with-photos
   Text on left, photo collage in a 2-column grid on the right.
   ========================================================= */
.slide[data-template="bio-with-photos"] .t-text {
    left: var(--s-edge);
    top: var(--s-edge);
    width: 38%;
}
.slide[data-template="bio-with-photos"] .t-text > .page-title {
    margin-bottom: var(--s-md);
}
.slide[data-template="bio-with-photos"] .t-text > .lead {
    margin-bottom: var(--s-md);
}
.slide[data-template="bio-with-photos"] .bio-photos {
    position: absolute;
    right: var(--s-edge);
    top: var(--s-edge);
    bottom: var(--s-edge);
    width: 50%;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    gap: var(--s-md);
}
.slide[data-template="bio-with-photos"] .bio-photos > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: var(--r-card);
    box-shadow: 0 2cqw 5cqw -1.5cqw rgba(13, 10, 11, 0.25);
}
/* When 3 photos: first one spans both rows on the right (the "hero") */
.slide[data-template="bio-with-photos"]
    .bio-photos[data-count="3"]
    > img:nth-child(1) {
    grid-column: 2;
    grid-row: 1 / span 2;
}
.slide[data-template="bio-with-photos"]
    .bio-photos[data-count="3"]
    > img:nth-child(2) {
    grid-column: 1;
    grid-row: 1;
}
.slide[data-template="bio-with-photos"]
    .bio-photos[data-count="3"]
    > img:nth-child(3) {
    grid-column: 1;
    grid-row: 2;
}
/* When 2 photos: side by side */
.slide[data-template="bio-with-photos"] .bio-photos[data-count="2"] {
    grid-template-rows: 1fr;
}
/* When 4+ photos: simple 2x2 grid (default) */

/* =========================================================
   TEMPLATE: detail-screen
   Text in left ~32% column, anchored at top ~22%. Media on the right
   in a flex container; phone+screen pairs render as <figure class="phone">
   with the screen clipped to the phone's inner rectangle.
   ========================================================= */
.slide[data-template="detail-screen"] .t-text {
    left: var(--s-edge);
    top: 22%;
    width: 32%;
}
.slide[data-template="detail-screen"] .t-text > .eyebrow {
    margin-bottom: var(--s-xs);
}
.slide[data-template="detail-screen"] .t-text > .headline {
    margin-bottom: var(--s-md);
}
.t-detail-media {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    width: 60%;
    padding: 5% 4%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-md);
}
.t-detail-media .phone {
    position: relative;
    height: 100%;
    aspect-ratio: 0.485; /* iPhone X+ aspect including frame */
    flex: 0 1 auto;
}
.t-detail-media .phone .phone-screen {
    position: absolute;
    inset: 1.5% 3.5% 1.5% 3.5%;
    border-radius: 9% / 4.4%;
    overflow: hidden;
    background: #efefef;
}
.t-detail-media .phone .phone-screen > img,
.t-detail-media .phone .phone-screen > video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top;
}
.t-detail-media .phone .phone-frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}
.t-detail-media > .t-detail-illustration {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
}
/* When the slide has no phones — illustration takes more breathing room */
.t-detail-media[data-phones="0"] {
    padding: 8% 6%;
}

/* =========================================================
   TEMPLATE: impact
   Same left-text/right-image pattern; bullets for stats
   ========================================================= */
.slide[data-template="impact"] .t-text {
    left: var(--s-edge);
    top: 22%;
    width: 40%;
}
.slide[data-template="impact"] .t-text > .eyebrow {
    margin-bottom: var(--s-xs);
}
.slide[data-template="impact"] .t-text > .headline {
    margin-bottom: var(--s-md);
}
.slide[data-template="impact"] .impact-illustration {
    position: absolute;
    right: var(--s-edge);
    top: 50%;
    transform: translateY(-50%);
    width: 30.4%; /* 80% of the previous 38% — illustration scales down across all Impact slides */
    max-height: 56%; /* 80% of the previous 70% */
    object-fit: contain;
    object-position: center right;
}
.stats {
    list-style: disc outside;
    padding-left: 1.2em;
    margin: var(--s-md) 0 0;
    display: flex;
    flex-direction: column;
    gap: var(--s-xs);
}
.stats > li {
    font-size: var(--fs-body);
    line-height: 1.45;
    color: var(--color-dark);
}
.stats > li::marker {
    color: var(--color-secondary);
}
/* Grouped stats: each <li> carries a project label above its stat text. */
.stats--grouped {
    gap: var(--s-md);
}
.stats--grouped .stat-label {
    display: block;
    font-size: var(--fs-list-item-title);
    font-weight: 700;
    color: var(--color-primary);
    margin: 0 0 var(--s-xs);
    line-height: 1.2;
}

/* 2-column stats grid with company logos.  Drop-in replacement for .stats
   when the impact has many entries with logos. */
.stats-grid {
    list-style: none;
    margin: var(--s-md) 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s-lg) var(--s-xl);
}
.stats-grid .stat-card {
    display: flex;
    flex-direction: column;
    gap: var(--s-xs);
    align-items: start;
}
.stats-grid .stat-body {
    display: flex;
    flex-direction: column;
    gap: var(--s-xs);
}
.stats-grid .stat-label {
    margin: 0;
    font-size: var(--fs-list-item-title);
    font-weight: 700;
    color: var(--color-secondary);
    line-height: 1.2;
}
.stats-grid .stat-body p {
    margin: 0;
    font-size: var(--fs-body);
    line-height: 1.4;
    color: var(--color-dark);
}

/* =========================================================
   TEMPLATE: numbered-list
   Page title + 1- or 2-col list. Optional illustration on the right.
   ========================================================= */
.slide[data-template="numbered-list"] .t-text {
    left: var(--s-edge);
    top: var(--s-edge);
    width: 72%;
    bottom: var(--s-edge);
}
.slide[data-template="numbered-list"] .t-text > .page-title {
    margin-bottom: var(--s-lg);
}
.slide[data-template="numbered-list"] .num-illustration {
    position: absolute;
    right: var(--s-edge);
    top: 50%;
    transform: translateY(-50%);
    width: 35%;
    max-height: 70%;
    object-fit: contain;
    object-position: center right;
}

/* =========================================================
   TEMPLATE: pull-quote
   Avatar + name on left, quote on right with green opening mark
   ========================================================= */
.slide[data-template="pull-quote"] .t-quote-attrib {
    position: absolute;
    left: var(--s-edge);
    top: 50%;
    transform: translateY(-50%);
    width: 18%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s-md);
}
.slide[data-template="pull-quote"] .pull-quote-avatar {
    width: 100%;
    aspect-ratio: 1;
    border-radius: 50%;
    object-fit: cover;
    box-shadow: 0 2cqw 5cqw -1.5cqw rgba(13, 10, 11, 0.3);
}
.slide[data-template="pull-quote"] .attrib-name {
    text-align: center;
    margin: 0;
    font-size: var(--fs-body);
    color: var(--color-med-gray);
}
.slide[data-template="pull-quote"] .moment-quote {
    position: absolute;
    left: 28%;
    right: var(--s-edge);
    top: 50%;
    transform: translateY(-50%);
    margin: 0;
    font-size: var(--fs-moment-quote);
    font-weight: 700;
    color: var(--color-dark);
    line-height: 1.1;
    letter-spacing: -0.01em;
}
.slide[data-template="pull-quote"] .moment-quote::before {
    content: "“";
    color: var(--color-secondary);
    font-size: 1.4em;
    line-height: 0;
    vertical-align: -0.1em;
    margin-right: 0.05em;
}

/* =========================================================
   TEMPLATE: quotes-list
   Page title + 2-col grid of quote blocks
   ========================================================= */
.slide[data-template="quotes-list"] .t-text {
    left: var(--s-edge);
    top: var(--s-edge);
    right: var(--s-edge);
    bottom: var(--s-edge);
}
.slide[data-template="quotes-list"] .t-text > .page-title {
    margin-bottom: var(--s-lg);
}
.quotes-grid {
    display: flex;
    flex-direction: column;
    gap: var(--s-sm);
}
.quotes-grid > blockquote {
    font-size: var(--fs-caption);
    color: var(--color-dark);
    margin: 0 0 var(--s-sm);
    padding-left: var(--s-md);
    border-left: 3px solid var(--color-secondary);
    break-inside: avoid;
    font-weight: 400;
}
.quotes-grid > blockquote cite {
    display: block;
    margin-top: 0.3cqw;
    font-size: 0.85cqw;
    font-weight: 500;
    color: var(--color-med-gray);
    font-style: normal;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* =========================================================
   TEMPLATE: vision
   ========================================================= */
.slide[data-template="vision"] .t-text {
    left: var(--s-edge);
    top: var(--s-edge);
    right: var(--s-edge);
    bottom: var(--s-edge);
}
.vision-body {
    columns: 2;
    column-gap: var(--s-xl);
}
.vision-body p {
    font-size: 0.95cqw;
    color: var(--color-med-gray);
    line-height: 1.55;
    margin: 0 0 var(--s-md);
    break-inside: avoid;
}

/* =========================================================
   TEMPLATE: project-grid
   Each card pairs one caption with one or more images. The <figure> carries
   the card's authored position; caption + images inside are CSS-positioned.
   ========================================================= */
.slide[data-template="project-grid"] .t-grid-card {
    position: absolute;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--s-sm);
}
.slide[data-template="project-grid"] .t-grid-card .caption {
    font-size: var(--fs-caption);
    color: var(--color-med-gray);
    font-weight: 400;
    line-height: 1.3;
    margin: 0;
    flex: 0 0 auto;
}
.award-badge {
    position: absolute;
    bottom: var(--s-sm);
    right: var(--s-sm);
    height: 5cqw;
    width: auto;
    border-radius: var(--r-sm);
    z-index: 2;
}
.slide[data-template="project-grid"] .t-grid-card-imgs {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    align-items: stretch;
    gap: var(--s-sm);
}
.slide[data-template="project-grid"] .t-grid-card-imgs > img {
    flex: 1 1 0;
    min-width: 0;
    width: auto;
    height: 100%;
    object-fit: contain;
    object-position: top;
}

/* Single-image card: image fills the space below the caption.
   Anchor to top-left so the image's visible left edge aligns with the
   caption (avoids the "caption hangs left of the image" gap when
   object-fit: contain leaves whitespace on either side of a wide image). */
.slide[data-template="project-grid"] .t-grid-card--single > img {
    flex: 1 1 auto;
    width: 100%;
    min-height: 0;
    object-fit: contain;
    object-position: top left;
}

/* Multi-image cards default to a single horizontal row (any count).
   Add `row-wrap` to the <figure> to opt into a wrapping multi-row grid
   sized so images stay readable. */
.slide[data-template="project-grid"] .t-grid-card.row-wrap .t-grid-card-imgs {
    flex-wrap: wrap;
    align-content: stretch;
    gap: var(--s-sm);
}
.slide[data-template="project-grid"]
    .t-grid-card.row-wrap[data-count="4"]
    .t-grid-card-imgs
    > img {
    flex: 0 1 calc(50% - var(--s-sm) / 2);
    height: calc(50% - var(--s-sm) / 2);
}
.slide[data-template="project-grid"]
    .t-grid-card.row-wrap[data-count="5"]
    .t-grid-card-imgs
    > img,
.slide[data-template="project-grid"]
    .t-grid-card.row-wrap[data-count="6"]
    .t-grid-card-imgs
    > img {
    flex: 0 1 calc(33.333% - var(--s-sm) * 2 / 3);
    height: calc(50% - var(--s-sm) / 2);
}
.slide[data-template="project-grid"]
    .t-grid-card.row-wrap[data-count="7"]
    .t-grid-card-imgs
    > img,
.slide[data-template="project-grid"]
    .t-grid-card.row-wrap[data-count="8"]
    .t-grid-card-imgs
    > img {
    flex: 0 1 calc(25% - var(--s-sm) * 3 / 4);
    height: calc(50% - var(--s-sm) / 2);
}

/* `stack` — flip the inner images to stack vertically (column) so each
   gets the full card width. */
.slide[data-template="project-grid"] .t-grid-card.stack .t-grid-card-imgs {
    flex-direction: column;
}
.slide[data-template="project-grid"]
    .t-grid-card.stack
    .t-grid-card-imgs
    > img {
    flex: 1 1 0;
    width: 100%;
    height: auto;
    min-height: 0;
}

/* =========================================================
   TEMPLATE: image-hero
   Photo collage. Layout chosen by data-count on .hero-photos.
   ========================================================= */
.slide[data-template="image-hero"] .hero-photos {
    position: absolute;
    inset: 0;
    display: grid;
    gap: 2px;
}
.slide[data-template="image-hero"] .hero-photos > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.hero-photos[data-count="1"] {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
}
.hero-photos[data-count="2"] {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr;
}
/* Add `stack` to .hero-photos to flip from side-by-side to vertically stacked */
.hero-photos.stack[data-count="2"] {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr 1fr;
}
.hero-photos[data-count="3"] {
    grid-template-columns: 1fr 2fr;
    grid-template-rows: 1fr 1fr;
}
.hero-photos[data-count="3"] > img:nth-child(1) {
    grid-column: 1;
    grid-row: 1;
}
.hero-photos[data-count="3"] > img:nth-child(2) {
    grid-column: 1;
    grid-row: 2;
}
.hero-photos[data-count="3"] > img:nth-child(3) {
    grid-column: 2;
    grid-row: 1 / span 2;
}
#s009 .hero-photos > img:nth-child(2) {
    object-position: bottom;
}
.hero-photos[data-count="4"] {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
}
.hero-photos[data-count="5"],
.hero-photos[data-count="6"],
.hero-photos[data-count="7"],
.hero-photos[data-count="8"] {
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: 1fr;
}
.t-hero-caption {
    position: absolute;
    top: var(--s-edge);
    left: var(--s-edge);
    margin: 0;
    z-index: 5;
    font-size: var(--fs-caption);
    color: var(--color-med-gray);
    background: rgba(255, 255, 255, 0.85);
    padding: var(--s-xs) var(--s-sm);
    border-radius: var(--r-sm);
}

/* =========================================================
   TEMPLATE: timeline (freeform — text and logos at authored positions)
   ========================================================= */
.slide[data-template="timeline"] .stage::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 26%;
    height: 2px;
    background: var(--color-secondary);
    pointer-events: none;
}
/* Push the section labels down a bit so they have breathing room below
   the green axis line. The .tb--section-label is absolutely positioned
   via inline `top:`, so we nudge with transform (which composes cleanly). */
.slide[data-template="timeline"] .tb--section-label {
    transform: translateY(var(--s-md));
}

/* =========================================================
   Per-slide entrance
   ========================================================= */
.slide.is-active .stage > .t-text,
.slide.is-active .stage > figcaption,
.slide.is-active .stage > figure {
    animation: rise var(--dur-slow) var(--ease-out) backwards;
}
.slide.is-active .stage > :nth-child(1):is(.t-text, figcaption, figure) {
    animation-delay: 0ms;
}
.slide.is-active .stage > :nth-child(2):is(.t-text, figcaption, figure) {
    animation-delay: 60ms;
}
.slide.is-active .stage > :nth-child(3):is(.t-text, figcaption, figure) {
    animation-delay: 120ms;
}
.slide.is-active .stage > :nth-child(4):is(.t-text, figcaption, figure) {
    animation-delay: 180ms;
}

@keyframes rise {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* =========================================================
   Section curtain — fade-through-black for section starts
   ========================================================= */
.section-curtain {
    position: fixed;
    inset: 0;
    background: var(--color-page-bg);
    z-index: 900;
    opacity: 0;
    pointer-events: none;
}
.section-curtain.is-closing {
    animation: curtainClose var(--dur) ease-in forwards;
}
.section-curtain.is-opening {
    animation: curtainOpen var(--dur) ease-out forwards;
}
@keyframes curtainClose {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes curtainOpen {
    from { opacity: 1; }
    to   { opacity: 0; }
}


/* =========================================================
   Controls
   ========================================================= */
.slide-chrome {
    position: fixed;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 16px;
    z-index: 10;
    opacity: 0;
    transition: opacity var(--dur-fast) ease;
}
body:hover .slide-chrome,
.slide-chrome:focus-within {
    opacity: 1;
}
.slide-controls {
    display: flex;
    align-items: center;
    gap: 8px;
    background: rgba(255, 255, 255, 0.85);
    backdrop-filter: blur(12px);
    border-radius: var(--r-pill);
    padding: 4px 10px;
    box-shadow: 0 8px 24px -8px rgba(13, 10, 11, 0.2);
    height: 42px;
}

.ctrl {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--color-dark);
    font-size: 14px;
    font-weight: 700;
    padding: 4px 10px;
    border-radius: var(--r-pill);
    transition: background-color var(--dur-fast);
}
.ctrl:hover {
    background: #efefef;
}
.ctrl:focus-visible {
    outline: 2px solid var(--color-secondary);
    outline-offset: 2px;
}
.ctrl-help {
    margin-left: 8px;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--color-light-gray);
    color: var(--color-med-gray);
    font-size: 16px;
    line-height: 1;
}
.ctrl-help:hover {
    border-color: var(--color-secondary);
    color: var(--color-secondary);
    background: transparent;
}

/* =========================================================
   Help overlay
   ========================================================= */
.help-overlay {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: rgba(13, 10, 11, 0.55);
    display: grid;
    place-items: center;
    animation: helpFade var(--dur) var(--ease-out);
}
.help-overlay[hidden] {
    display: none;
}
@keyframes helpFade {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}
.help-card {
    position: relative;
    background: var(--color-page-bg);
    color: var(--color-dark);
    border-radius: 12px;
    padding: 32px 40px 28px;
    width: min(440px, 90vw);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
    font-family: var(--font-sans);
}
.help-card h2 {
    margin: 0 0 20px;
    font-size: 22px;
    font-weight: 700;
    color: var(--color-dark);
    letter-spacing: -0.01em;
}
.help-list {
    margin: 0;
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 24px;
    row-gap: 12px;
    align-items: center;
    font-size: 14px;
}
.help-list dt {
    display: flex;
    gap: 4px;
    align-items: center;
    color: var(--color-dark);
    font-weight: 500;
    white-space: nowrap;
}
.help-list dd {
    margin: 0;
    color: var(--color-med-gray);
}
.help-list kbd {
    display: inline-block;
    min-width: 28px;
    padding: 2px 6px;
    border: 1px solid var(--color-light-gray);
    border-bottom-width: 2px;
    border-radius: 4px;
    background: #fafafa;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px;
    text-align: center;
    color: var(--color-dark);
}
.help-foot {
    margin: 24px 0 0;
    padding-top: 16px;
    border-top: 1px solid #eee;
    font-size: 12px;
    color: var(--color-med-gray);
}
.help-foot a {
    color: var(--color-primary);
    text-decoration: none;
}
.help-foot a:hover {
    text-decoration: underline;
}
.help-close {
    appearance: none;
    position: absolute;
    top: 12px;
    right: 12px;
    width: 28px;
    height: 28px;
    border: 0;
    background: transparent;
    border-radius: 50%;
    font-size: 22px;
    line-height: 1;
    color: var(--color-med-gray);
    cursor: pointer;
}
.help-close:hover {
    background: #efefef;
    color: var(--color-dark);
}

.slide-counter {
    font-size: 11px;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--color-med-gray);
    min-width: 3ch;
    text-align: center;
}

.progress {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: transparent;
    z-index: 10;
}
.progress-bar {
    display: block;
    height: 100%;
    width: 0%;
    background: linear-gradient(
        90deg,
        var(--color-secondary),
        var(--color-primary)
    );
    transition: width var(--dur) var(--ease-out);
}

@view-transition {
    navigation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: var(--dur);
    animation-timing-function: var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
    .slide,
    .slide.is-active *,
    .progress-bar {
        animation: none !important;
        transition: none !important;
    }
}

@media print {
    html,
    body {
        overflow: visible;
        height: auto;
        background: #fff;
    }
    .slide-chrome,
    .progress {
        display: none;
    }
    .slide {
        position: relative;
        inset: auto;
        opacity: 1 !important;
        page-break-after: always;
        height: 100vh;
    }
}

/* =========================================================
   Template: full-video — single video filling the stage edge-to-edge
   ========================================================= */
.slide[data-template="full-video"] .stage {
    background: var(--color-page-bg);
}
.slide[data-template="full-video"] .full-video {
    position: absolute;
    inset: var(--s-edge) 0; /* top/bottom padding matches other slides */
    width: 100%;
    height: calc(100% - var(--s-edge) * 2);
    object-fit: contain; /* swap to "cover" if you want it to fill at the cost of cropping */
    object-position: center;
}

/* =========================================================
   Per-slide overrides
   Anything that's unique to ONE slide (e.g. nudging a video inside its
   phone frame) goes here. Use the slide id (#sNNN) as the scope so the
   rule only applies to that slide.
   ========================================================= */

/* --- s013-s021, s068-s071: small drop shadow on grid images --- */
#s012 .t-grid-card img,
#s013 .t-grid-card img,
#s014 .t-grid-card img,
#s015 .t-grid-card img,
#s016 .t-grid-card img,
#s017 .t-grid-card img,
#s018 .t-grid-card img,
#s019 .t-grid-card img,
#s020 .t-grid-card img,
#s067 .t-grid-card img,
#s068 .t-grid-card img,
#s069 .t-grid-card img,
#s070 .t-grid-card img {
    filter: var(--shadow-sm);
}

/* --- s072: text on top (full-width), image below (full-width) --- */

/* --- s088: full-width Impact (illustration removed; 2-col stats) --- */
#s088 .t-text {
    inset: var(--s-edge);
    width: auto;
    max-width: none;
    right: var(--s-edge);
    color: var(--color-dark);
}

#s071 .stage {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: var(--s-edge);
    gap: var(--s-lg);
}
#s071 .t-text,
#s071 .t-detail-media {
    position: static;
    inset: auto;
    width: 100%;
    max-width: none;
}
#s071 .t-text {
    flex: 0 0 auto;
}
#s071 .t-detail-media {
    flex: 1 1 auto;
    min-height: 0;
    padding: 0; /* override the default 8% 6% on data-phones="0" */
    display: flex;
    justify-content: flex-start;
    align-items: center;
}
#s071 .t-detail-illustration {
    width: 100%;
    max-width: 100%;
    max-height: 100%;
    height: auto;
    object-fit: contain;
    object-position: left center;
}

/* --- s043: "Starting to get somewhere" video --- */
#s042 .phone-screen > video {
    /* Crop anchor inside the phone screen. Center is default; try
       "top", "bottom", or explicit "<x>% <y>%" e.g. "50% 30%". */
    object-position: center;

    /* Zoom in/out and nudge the video without changing the phone frame.
       transform-origin: top-left so percentages count from the top edge. */
    transform: none; /* e.g. scale(1.05) translate(0, -2%) */
    transform-origin: 50% 50%;
    width: auto;
    height: 109%;
    position: relative;
    top: -5.5%;
    left: -8.5%;
}

/* --- s044: "Vision Prototype" video --- */
#s043 .phone-screen > video {
    object-position: center;
    transform: none;
    transform-origin: 50% 50%;
    width: auto;
    height: 104%;
    position: relative;
    top: -1.5%;
    left: -2.5%;
}

#s057 .stage .t-text,
#s064 .stage .t-text {
    width: 64%;
}

/* --- s044: "Vision Prototype" video --- */
#s066 .phone-screen > img {
    object-position: center;
    transform: none;
    transform-origin: 50% 50%;
    width: auto;
    height: 107%;
    position: relative;
    top: -3.5%;
    left: -1%;
}

/* Size modifiers for detail illustrations. Drop the class onto the <img>
   alongside .t-detail-illustration. */
.t-detail-media > .t-detail-illustration.size-sm {
    max-width: 64%;
    max-height: 64%;
}
.t-detail-media > .t-detail-illustration.size-md {
    max-width: 72%;
    max-height: 72%;
}
.t-detail-media > .t-detail-illustration.size-lg {
    max-width: 88%;
    max-height: 88%;
}

/* Impact illustration: base width is 38%; size-* multiplies that. */
.slide[data-template="impact"] .impact-illustration.size-sm {
    width: calc(38% * 0.6);
    max-height: 42%;
}
.slide[data-template="impact"] .impact-illustration.size-md {
    width: calc(38% * 0.8);
    max-height: 56%;
}
.slide[data-template="impact"] .impact-illustration.size-lg {
    width: calc(38% * 0.9);
    max-height: 63%;
}

/* =========================================================
   Stamps — emoji reaction layer
   ========================================================= */

/* Menu button — inside .slide-chrome, left of controls */
.menu-btn {
    appearance: none;
    border: 0;
    background: rgba(255, 255, 255, 0.85);
    backdrop-filter: blur(12px);
    width: 42px;
    height: 42px;
    border-radius: 50%;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 8px 24px -8px rgba(13, 10, 11, 0.2);
    transition: background-color var(--dur-fast);
    display: grid;
    place-items: center;
    flex-shrink: 0;
}
.menu-btn:hover {
    background: #efefef;
}
.menu-btn[aria-expanded="true"] {
    background: #efefef;
}

/* Section jump menu */
.section-menu {
    position: fixed;
    bottom: 72px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(12px);
    border-radius: var(--r-lg);
    padding: 6px 0;
    box-shadow: 0 8px 24px -8px rgba(13, 10, 11, 0.2);
    z-index: 11;
    animation: sectionMenuIn var(--dur-fast) var(--ease-out);
    min-width: 220px;
}
.section-menu[hidden] {
    display: none;
}
@keyframes sectionMenuIn {
    from {
        opacity: 0;
        transform: translateX(-50%) translateY(8px) scale(0.95);
    }
    to {
        opacity: 1;
        transform: translateX(-50%) translateY(0) scale(1);
    }
}
.section-menu-item {
    display: block;
    padding: 8px 18px;
    font-family: var(--font-sans);
    font-size: 14px;
    font-weight: 500;
    color: var(--color-dark);
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--dur-fast);
    white-space: nowrap;
}
.section-menu-item:hover {
    background: rgba(0, 0, 0, 0.06);
}
.section-menu-item.is-current {
    color: var(--color-primary);
}

/* Stamp button — inside .slide-chrome, right of controls */
.stamp-btn {
    appearance: none;
    border: 0;
    background: rgba(255, 255, 255, 0.85);
    backdrop-filter: blur(12px);
    width: 42px;
    height: 42px;
    border-radius: 50%;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 8px 24px -8px rgba(13, 10, 11, 0.2);
    transition: background-color var(--dur-fast);
    display: grid;
    place-items: center;
    flex-shrink: 0;
}
.stamp-btn:hover {
    background: #efefef;
}
.stamp-btn[aria-expanded="true"] {
    background: #efefef;
}
.stamp-btn.is-offline {
    opacity: 0.35;
    pointer-events: none;
}

/* Emoji picker menu */
.stamp-menu {
    position: fixed;
    bottom: 64px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 4px;
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(12px);
    border-radius: var(--r-pill);
    padding: 6px 10px;
    box-shadow: 0 8px 24px -8px rgba(13, 10, 11, 0.2);
    z-index: 11;
    animation: stampMenuIn var(--dur-fast) var(--ease-out);
}
.stamp-menu[hidden] {
    display: none;
}
@keyframes stampMenuIn {
    from {
        opacity: 0;
        transform: translateX(-50%) translateY(8px) scale(0.95);
    }
    to {
        opacity: 1;
        transform: translateX(-50%) translateY(0) scale(1);
    }
}
.stamp-option {
    appearance: none;
    border: 0;
    background: transparent;
    font-size: 24px;
    padding: 6px 8px;
    border-radius: 8px;
    cursor: pointer;
    transition:
        background-color var(--dur-fast),
        transform var(--dur-fast);
    line-height: 1;
}
.stamp-option:hover {
    background: #efefef;
    transform: scale(1.2);
}

/* Drop-mode cursor — set dynamically via JS (emoji image) */
body.is-stamping .stage {
    cursor: inherit;
}
body.is-stamping .slide-chrome {
    pointer-events: none;
    opacity: 0.5;
}
body.is-stamping .stamp-menu {
    pointer-events: none;
    opacity: 0.5;
}

/* Stamps on slides */
.stamp {
    position: absolute;
    font-size: 2.24cqw;
    line-height: 1;
    z-index: 5;
    pointer-events: auto;
    user-select: none;
    animation: stampPop var(--dur-fast) var(--ease-out);
    transform-origin: center center;
}
@keyframes stampPop {
    0% {
        transform: scale(0);
        opacity: 0;
    }
    60% {
        transform: scale(1.3);
    }
    100% {
        transform: scale(1);
        opacity: 1;
    }
}
/* Nametag on hover */
.stamp::before {
    content: attr(data-user-name);
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-top: 2px;
    padding: 2px 8px;
    font-family: var(--font-sans);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-dark);
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(8px);
    border-radius: var(--r-pill);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-fast);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
.stamp:hover::before {
    opacity: 1;
}

.stamp[data-mine="true"] {
    cursor: pointer;
}
.stamp[data-mine="true"]::after {
    content: "×";
    position: absolute;
    top: -6px;
    right: -6px;
    width: 16px;
    height: 16px;
    font-size: 12px;
    line-height: 16px;
    text-align: center;
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    border-radius: 50%;
    opacity: 0;
    transition: opacity var(--dur-fast);
    pointer-events: none;
}
.stamp[data-mine="true"]:hover::after {
    opacity: 1;
}

/* =========================================================
   Utility classes
   ========================================================= */
.has-shadow,
.has-shadow-md {
    filter: var(--shadow-md);
}
.has-shadow-sm {
    filter: var(--shadow-sm);
}
.has-shadow-lg {
    filter: var(--shadow-lg);
}
