/* ============================================================
   THEME: minimal and photo-first. Near-black, monospace "typewriter" text,
   heavy display type, and one accent color (yellow) used for highlights.
   The only comic-book touch is halftone dots on photos. Change colors here.
   ============================================================ */
:root,
[data-bs-theme="dark"] {
  --accent: #ffd23f;
  --accent-hover: #ffe27a;
  --ink: #0e0e10;
  --bs-body-bg: #0e0e10;
  --bs-body-color: #e8e6e1;
  --bs-secondary-color: #8f8c86;
  --panel: #161618;
  --line: rgba(232, 230, 225, .12);
  --bs-body-font-family: "Space Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
  --bs-body-font-size: .95rem;
  --bs-link-color-rgb: 232, 230, 225;
  --bs-link-hover-color-rgb: 255, 210, 63;
  --display: "Archivo Black", "Arial Black", sans-serif;
  /* Halftone dot pattern (the comic touch), reused on photos */
  --halftone: radial-gradient(rgba(0,0,0,.6) 1.3px, transparent 1.7px);
}

html { scroll-padding-top: 64px; }
body { -webkit-font-smoothing: antialiased; overflow-x: clip; }
::selection { background: var(--accent); color: #000; }
a { text-decoration: none; }

.skip-link { position: absolute; top: 8px; left: 8px; z-index: 2000; background: var(--accent); color: #000; padding: 8px 14px; }

/* Highlighted words: black text on a yellow box */
mark { background: var(--accent); color: #000; padding: 0 .3em; }

/* ---------- Type ---------- */
.section-title, .brand {
  font-family: var(--display); font-weight: 400; text-transform: uppercase; letter-spacing: -.01em; color: var(--bs-body-color);
}
.section-title { font-size: clamp(2.2rem, 6vw, 4.6rem); line-height: .92; }
.eyebrow { font-size: .78rem; letter-spacing: .14em; text-transform: uppercase; color: var(--accent); margin-bottom: .8rem; }

/* ---------- Buttons: flat, square, typewriter labels ---------- */
.btn { font-family: var(--bs-body-font-family); font-weight: 700; text-transform: uppercase; letter-spacing: .08em; font-size: .8rem; border-radius: 0; padding: .7rem 1.1rem; border-width: 1px; transition: background-color .15s, color .15s, border-color .15s; }
.btn-name { text-transform: none; letter-spacing: .02em; }   /* the name keeps its own capitals: ThatSubscriberGuy */
.btn-lg { font-size: .9rem; padding: .9rem 1.4rem; }
.btn-sm { font-size: .72rem; padding: .5rem .8rem; }
.btn-accent {
  --bs-btn-bg: var(--accent); --bs-btn-border-color: var(--accent); --bs-btn-color: #000;
  --bs-btn-hover-bg: var(--accent-hover); --bs-btn-hover-border-color: var(--accent-hover); --bs-btn-hover-color: #000;
  --bs-btn-active-bg: var(--accent); --bs-btn-active-border-color: var(--accent); --bs-btn-active-color: #000;
  --bs-btn-focus-shadow-rgb: 255, 210, 63;
}
.btn-outline-light { --bs-btn-color: var(--bs-body-color); --bs-btn-border-color: var(--line); --bs-btn-hover-bg: transparent; --bs-btn-hover-color: var(--accent); --bs-btn-hover-border-color: var(--accent); --bs-btn-active-bg: transparent; --bs-btn-active-color: var(--accent); }
.ig { width: 1.1em; height: 1.1em; fill: none; stroke: currentColor; stroke-width: 2; }
.ig .dot { fill: currentColor; stroke: none; }

/* ---------- Nav: yellow logo block on the left, links on the right ---------- */
.site-nav { padding: 0; min-height: 52px; background: rgba(14,14,16,.0); border-bottom: 1px solid var(--line); transition: background-color .3s, transform .35s ease; }
/* Menu hides while scrolling down and comes back when scrolling up */
.site-nav.tucked { transform: translateY(-100%); }
.site-nav.scrolled { background: rgba(14,14,16,.92); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.brand { display: flex; align-items: center; height: 52px; padding: 0 22px; margin: 0; font-size: 1.35rem; background: var(--accent); color: #000 !important; }
.site-nav .nav-link { font-size: .8rem; text-transform: uppercase; letter-spacing: .12em; color: var(--bs-secondary-color); padding: .5rem .7rem !important; }
.site-nav .nav-link:hover, .site-nav .nav-link.active { color: var(--accent); }
.navbar-toggler { border: 1px solid var(--line); border-radius: 0; }
@media (min-width: 768px) {
  /* A slanted yellow block behind the current link, springing along to whichever link the mouse is on (script.js) */
  .nav-slide #mainNav { position: relative; }
  .nav-slide .nav-blob { position: absolute; top: 50%; height: 30px; margin-top: -15px; left: 0; width: 0; background: var(--accent); transform: skewX(-12deg); opacity: 0; pointer-events: none; transition: left .45s cubic-bezier(.3,1.35,.4,1), width .45s cubic-bezier(.3,1.35,.4,1), opacity .2s; }
  .nav-slide .nav-item { position: relative; z-index: 1; }
  .nav-slide .nav-link { transition: color .2s; }
  .nav-slide .nav-link.under, .nav-slide .nav-link.under:hover { color: var(--ink); font-weight: 700; }
  .nav-slide .nav-link:hover:not(.under) { color: #fff; }
}
@media (max-width: 767.98px) {
  .site-nav .navbar-collapse { background: var(--ink); padding: 8px 16px 14px; border-top: 1px solid var(--line); }
}

/* ---------- Hero: giant TSG with photos through the letters; scrolling zooms through the "S" ----------
   The hero is tall; its stage sticks to the screen while you scroll through it.
   JS sets --z on the stage: 0 at the top, 1 when the photo fills the screen. */
.hero { position: relative; height: 260vh; }
.hero-stage { position: sticky; top: 0; height: 100svh; overflow: hidden; background: var(--ink); }
.zoom-photo {
  position: absolute; inset: 0; background-size: cover; background-position: var(--fx, 50%) var(--fy, 35%);
  opacity: 0; transition: opacity 1.1s ease;
  transform: scale(calc(1.14 - var(--z, 0) * .14));
  filter: brightness(1.15) contrast(1.06) saturate(1.08);
  will-change: transform;   /* its own layer: the filter is drawn once, not again on every scroll frame */
}
.zoom-photo.show { opacity: 1; }
/* The wrapper takes the fade-in, so the letters' own scroll zoom (a CSS transform set in script.js) isn't overridden by it */
.zoom-mask-wrap { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
/* The SVG only places and measures the letters (the intro lines up with it); it's never shown, because an SVG
   mask redrawn on every scroll step is slow on phones. The canvas draws the same thing, quickly */
.zoom-mask { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; visibility: hidden; }
.zoom-canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
#zoomText { font-family: var(--display); }
/* Past the end of the zoom the photo flies down into its Edits tile (script.js): a fixed copy takes over
   from the stage, starting as the whole screen with the same look, and ends as the tile with the tile's look */
.hero.flown .zoom-photo { visibility: hidden; }
/* Pinned to the screen for the first half of its flight and placed on the page for the second (script.js sets
   which), so on iPhones it rides along with whatever it's closest to instead of shaking against it */
.flyer { position: fixed; z-index: 1020; left: 0; top: 0; overflow: hidden; pointer-events: none; display: none; transform-origin: 50% 50%; background: var(--panel); box-shadow: 0 calc(var(--lift, 0) * 40px) calc(var(--lift, 0) * 80px) rgba(0, 0, 0, calc(var(--lift, 0) * .7)); outline: 2px solid rgba(255, 210, 63, calc(var(--lift, 0) * .9)); outline-offset: 0; }
.flyer.on { display: block; }
.flyer-photo { position: absolute; inset: 0; background-size: cover; filter: brightness(calc(1.15 - var(--land, 0) * .15)) contrast(calc(1.06 - var(--land, 0) * .06)) saturate(calc(1.08 - var(--land, 0) * .08)); }
.edit-tile.landing img { opacity: 0; }
/* Intro text, clock and buttons: fade away as soon as the dive starts */
.hero-ui { position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; justify-content: space-between; padding: 72px 0 22px; opacity: clamp(0, 1 - var(--z, 0) * 6, 1); pointer-events: none; }
.hero-ui a, .hero-ui button { pointer-events: auto; }
.hero-top, .hero-bottom { position: relative; z-index: 2; padding: 0 22px; }
.hero-intro { display: flex; flex-wrap: wrap; align-items: baseline; gap: .1em .5em; font-weight: 700; pointer-events: auto; }
/* The name is the headline of this corner: big display type, so its squeeze to a yellow TSG echoes the giant letters */
.hero-handle { font-family: var(--display); font-weight: 400; font-size: clamp(1.6rem, 3.4vw, 2.6rem); line-height: 1; letter-spacing: -.01em; color: var(--bs-body-color); }
/* Squeeze to the initials: the other letters collapse to nothing and the T, S and G close up in yellow */
.hero-handle .x, .hero-handle .k { display: inline-block; vertical-align: bottom; }
.hero-handle .x { max-width: 1.2em; overflow: hidden; transition: max-width .45s cubic-bezier(.7,0,.2,1), opacity .3s; }
.hero-handle .k { transition: color .3s; }
.hero-handle.squeeze .x { max-width: 0; opacity: 0; }
.hero-handle.squeeze .k { color: var(--accent); }
.hero-sep { color: var(--bs-secondary-color); font-weight: 400; }
/* Intro text: white and a size up, typed in letter by letter (script.js) with a block cursor that keeps blinking at the end */
.hero-lead { max-width: 40ch; color: #fff; font-size: clamp(.98rem, 1.25vw, 1.15rem); line-height: 1.55; text-shadow: 0 1px 10px rgba(0, 0, 0, .8); }
.hero-lead .c { opacity: 0; }
.hero-lead .c.on { opacity: 1; }
.hero-lead .cur { display: inline-block; width: .6em; height: 1.05em; margin: 0 calc(-.6em - 2px) 0 2px; vertical-align: -.15em;   /* takes up no room, so nothing reflows as it moves */ background: var(--accent); animation: blink 1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }
.hero-bottom { display: flex; justify-content: space-between; align-items: flex-end; font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; }
.hero-bottom .dim { color: var(--bs-secondary-color); }
.scroll-more { margin-left: 1.2em; color: var(--bs-body-color); }
.scroll-more:hover { color: var(--accent); }


/* ---------- Sections ---------- */
.section { padding: 90px 0; }
.section-alt { background: var(--panel); border-block: 1px solid var(--line); }

/* ---------- Shoots: character select screen ---------- */
/* Stage: the cover photo fills the stage but only shows through an angled frame; the cut-out of the same photo
   sits exactly on top of it, unclipped, so whatever of the person reaches past the frame pops out of it.
   The character's name runs huge behind them. Shots sit to the right, the roster runs along the bottom. */
.sel-top { display: grid; grid-template-columns: 1.6fr 1fr; gap: 40px; align-items: end; }
.sel-stage { position: relative; height: clamp(420px, 70vh, 700px); }
.sel-frame { position: absolute; inset: 0; overflow: hidden; background: var(--panel); clip-path: polygon(17% 30%, 91% 30%, 83% 100%, 9% 100%); }
.sel-frame::after { content: ""; position: absolute; inset: 0; background-image: var(--halftone); background-size: 6px 6px; opacity: .5; }
.sel-photo { width: 100%; height: 100%; object-fit: cover; filter: brightness(.42) saturate(.85) blur(2px); }
.sel-bigname { position: absolute; left: 0; right: 0; top: 14%; z-index: 1; margin: 0; font-family: var(--display); font-size: clamp(2.6rem, 7.5vw, 7rem); line-height: .86; text-align: center; text-transform: uppercase; text-wrap: balance; color: transparent; -webkit-text-stroke: 1.5px rgba(255, 210, 63, .7); pointer-events: none; }
/* Same size and crop as .sel-photo (script.js gives both the same object-position), so they line up exactly */
.sel-cut { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; object-fit: cover; filter: drop-shadow(0 16px 24px rgba(0, 0, 0, .7)); pointer-events: none; }
.sel-stage.no-cut .sel-cut { display: none; }
.sel-stage.no-cut .sel-photo { filter: none; }
/* No pop-out: the slanted window opens to the whole photo, so nothing (like a head) hides above it */
.sel-stage.no-cut .sel-frame { clip-path: polygon(7% 0, 100% 0, 93% 100%, 0 100%); }
/* The photo's own box (sized in script.js to the photo's shape, sitting on the stage's bottom); the frame,
   cut-out and glitch faces all live in it, so they line up with the whole, uncropped photo */
.sel-box { position: absolute; left: 0; top: 0; width: 100%; height: 100%; }
/* ?frames preview only: the switch for trying each character's framing */
.frame-switch { position: fixed; z-index: 1100; left: 16px; bottom: 16px; padding: 10px 14px; border: 0; background: var(--accent); color: var(--ink); font: 700 .78rem/1.3 var(--bs-font-monospace, monospace); text-align: left; box-shadow: 0 10px 30px rgba(0, 0, 0, .5); cursor: pointer; }
.frame-switch span { display: block; font-weight: 400; opacity: .7; }
.sel-num { margin: 0 0 6px; font-size: .78rem; letter-spacing: .14em; color: var(--accent); }
.sel-name { margin: 0 0 4px; font-family: var(--display); font-size: clamp(1.8rem, 3.2vw, 2.8rem); line-height: .95; text-transform: uppercase; }
.sel-count { margin: 0 0 16px; font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--bs-secondary-color); }
/* A character with lots of shots scrolls inside the panel instead of stretching the page */
.sel-shots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; max-height: min(50vh, 500px); overflow-y: auto; padding-right: 6px; scrollbar-width: thin; scrollbar-color: var(--accent) rgba(255, 255, 255, .08); }
.sel-shots::-webkit-scrollbar { width: 4px; }
.sel-shots::-webkit-scrollbar-track { background: rgba(255, 255, 255, .08); }
.sel-shots::-webkit-scrollbar-thumb { background: var(--accent); }
.sel-shot { position: relative; padding: 0; border: 0; aspect-ratio: 4 / 5; overflow: hidden; background: var(--panel); cursor: pointer; }
.sel-shot img, .sel-shot .ph { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .5s cubic-bezier(.2,.7,.2,1); }
.sel-shot:hover img { transform: scale(1.06); }
/* Videos get a slanted yellow play badge in the middle */
.sel-play { position: absolute; left: 50%; top: 50%; width: 42px; height: 42px; margin: -21px 0 0 -21px; background: var(--accent); transform: skewX(-10deg); transition: transform .25s; }
.sel-play::after { content: ""; position: absolute; left: 16px; top: 12px; border-style: solid; border-width: 9px 0 9px 14px; border-color: transparent transparent transparent var(--ink); transform: skewX(10deg); }
.sel-shot:hover .sel-play { transform: skewX(-10deg) scale(1.12); }
.sel-shot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Secret set: a character's stage glitches now and then (script.js); clicking during a glitch breaks it open.
   The glitch (~0.9s): the photo dims, goes sick green and stutters in slices; a face from the secret set
   flashes through like a bad signal; the cut-out splits green / purple and the name flickers to HA HA HA */
/* No box: the faces are dark glitch shots, so "screen" drops their black background and a soft oval mask
   fades the edges, leaving just the glowing face floating over the stage */
.sel-flash { position: absolute; inset: 0; z-index: 3; width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; opacity: 0; pointer-events: none; mix-blend-mode: screen;
  -webkit-mask-image: radial-gradient(ellipse 46% 40% at 50% 42%, #000 35%, transparent 100%); mask-image: radial-gradient(ellipse 46% 40% at 50% 42%, #000 35%, transparent 100%); }
.sel-stage.glitch .sel-frame { animation: frameGlitch .9s steps(1) both; }
.sel-stage.glitch .sel-cut { animation: cutGlitch .9s steps(1) both; }
.sel-stage.glitch .sel-flash { animation: faceFlash .9s steps(1) both; }
.sel-stage.glitch .sel-bigname { animation: nameGlitch .9s steps(1) both; }
.sel-stage.breaking .sel-flash { animation-name: faceFlashHard; }
@keyframes frameGlitch {
  0% { transform: translateX(-6px); filter: brightness(.5) hue-rotate(70deg) saturate(1.8); }
  10% { transform: translateX(9px); clip-path: polygon(17% 30%, 91% 30%, 89% 47%, 15% 47%, 13% 60%, 87% 60%, 83% 100%, 9% 100%); }
  22% { transform: translateX(-3px) skewX(4deg); filter: brightness(.25) contrast(1.6) hue-rotate(70deg); }
  36% { transform: translateX(12px); clip-path: polygon(17% 30%, 91% 30%, 90% 38%, 16% 38%, 12% 76%, 86% 76%, 83% 100%, 9% 100%); filter: brightness(.6) hue-rotate(-50deg) saturate(2); }
  52% { transform: none; filter: brightness(.18) grayscale(1); }
  64% { transform: translateX(-10px); clip-path: polygon(17% 30%, 91% 30%, 88% 55%, 14% 55%, 13% 66%, 87% 66%, 83% 100%, 9% 100%); filter: brightness(.45) hue-rotate(70deg); }
  80% { transform: translateX(4px); filter: brightness(.35) contrast(1.5); }
  92%, 100% { transform: none; filter: none; }
}
@keyframes cutGlitch {
  0% { transform: translateX(5px); filter: drop-shadow(-7px 0 #6fdc3c) drop-shadow(7px 0 #a34be0) brightness(.7); }
  14% { transform: translateX(-10px); clip-path: inset(0 0 52% 0); }
  28% { transform: translateX(6px) scale(1.02); clip-path: inset(40% 0 0 0); filter: drop-shadow(6px 0 #6fdc3c) drop-shadow(-6px 0 #a34be0) brightness(.5); }
  44% { opacity: 0; }
  58% { opacity: 1; transform: translateX(-4px); clip-path: inset(0 0 20% 0); filter: drop-shadow(-4px 0 #a34be0) grayscale(1) brightness(.6); }
  74% { transform: translateX(8px); clip-path: inset(25% 0 0 0); }
  90%, 100% { transform: none; clip-path: none; filter: drop-shadow(0 16px 24px rgba(0, 0, 0, .7)); opacity: 1; }
}
/* The faces flicker through the middle of the glitch; the second layer is blended over the first
   (lighten), shifted and scaled a little, so two faces fuse into one shifting face */
.sel-flash-b { mix-blend-mode: lighten; }   /* fuses with the first face (both drop their dark backgrounds) */
.sel-stage.glitch .sel-flash-b { animation-name: faceFlashB; }
@keyframes faceFlash {
  0%, 12% { opacity: 0; }
  15% { opacity: .8; transform: translateX(-8px) scale(1.04); filter: drop-shadow(6px 0 #6fdc3c); }
  22% { opacity: .35; }
  30% { opacity: .9; transform: translateX(5px) scale(1.08); filter: drop-shadow(-6px 0 #a34be0) contrast(1.4); }
  40% { opacity: .5; transform: scale(1.1); }
  48% { opacity: .95; transform: translateX(-4px) scale(1.14); filter: contrast(1.5); }
  58% { opacity: .6; }
  66% { opacity: .9; transform: translateX(6px) scale(1.16); filter: drop-shadow(-5px 0 #6fdc3c); }
  76% { opacity: 0; }
  100% { opacity: 0; }
}
@keyframes faceFlashB {
  0%, 18% { opacity: 0; }
  20% { opacity: .55; transform: translateX(14px) scale(1.12); filter: hue-rotate(60deg); }
  34% { opacity: .3; transform: translateX(-10px) scale(1.06); }
  44% { opacity: .7; transform: translateX(8px) scale(1.2); filter: hue-rotate(-40deg) contrast(1.5); }
  56% { opacity: .4; transform: scale(1.1); }
  64% { opacity: .65; transform: translateX(-12px) scale(1.18); }
  74%, 100% { opacity: 0; }
}
@keyframes faceFlashHard {
  0% { opacity: 0; }
  12% { opacity: .9; transform: scale(1.05); }
  30% { opacity: .6; transform: translateX(10px) scale(1.15); filter: drop-shadow(-8px 0 #a34be0); }
  50% { opacity: 1; transform: scale(1.3); filter: contrast(1.6); }
  75% { opacity: 1; transform: scale(1.45); }
  100% { opacity: 0; transform: scale(1.6); }
}
.sel-stage.breaking .sel-flash-b { animation-name: faceFlashHard; animation-direction: reverse; }@keyframes nameGlitch {
  0% { transform: translateX(-12px); -webkit-text-stroke-color: #6fdc3c; }
  20% { transform: translateX(6px) skewX(-8deg); -webkit-text-stroke-color: #a34be0; }
  40% { transform: translateX(-4px); -webkit-text-stroke-color: #6fdc3c; color: rgba(111, 220, 60, .12); }
  70% { transform: translateX(10px); -webkit-text-stroke-color: #a34be0; }
  90%, 100% { transform: none; }
}.secret-key { position: absolute; z-index: 4; left: 10px; bottom: 10px; }.secret { position: relative; margin-top: 28px; padding: 26px 22px 22px; background: #0b0b0d; border-top: 3px solid #6fdc3c; }
.secret::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: repeating-linear-gradient(transparent 0 3px, rgba(255, 255, 255, .025) 3px 4px); }   /* faint scan lines */
.secret.open { animation: secretIn .6s cubic-bezier(.2,.9,.25,1.1); }
@keyframes secretIn { from { opacity: 0; transform: translateY(24px) skewY(-1.5deg); clip-path: inset(0 0 100% 0); } to { opacity: 1; transform: none; clip-path: inset(0); } }
.secret-head { position: relative; display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 18px; margin-bottom: 18px; }
.secret-kicker { width: 100%; margin: 0; color: #6fdc3c; font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; }
/* The title glitches: green and purple copies jitter behind it now and then */
.secret-title { position: relative; margin: 0; font-family: var(--display); font-size: clamp(1.8rem, 4.5vw, 3.6rem); line-height: .95; text-transform: uppercase; }
.secret-title::before, .secret-title::after { content: attr(data-text); position: absolute; inset: 0; pointer-events: none; }
.secret-title::before { color: #6fdc3c; animation: glitchA 3.2s steps(1) infinite; }
.secret-title::after { color: #a34be0; animation: glitchB 3.2s steps(1) infinite; }
@keyframes glitchA { 0%, 86%, 100% { transform: none; opacity: 0; clip-path: none; } 88% { transform: translate(-4px, 1px); opacity: .9; clip-path: inset(10% 0 55% 0); } 92% { transform: translate(3px, -1px); opacity: .9; clip-path: inset(60% 0 8% 0); } }
@keyframes glitchB { 0%, 86%, 100% { transform: none; opacity: 0; clip-path: none; } 89% { transform: translate(4px, 0); opacity: .9; clip-path: inset(40% 0 30% 0); } 93% { transform: translate(-3px, 2px); opacity: .9; clip-path: inset(5% 0 70% 0); } }
.secret-close { margin-left: auto; padding: 6px 12px; background: transparent; color: var(--bs-secondary-color); border: 1px solid var(--line); font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; cursor: pointer; }
.secret-close:hover { color: #6fdc3c; border-color: #6fdc3c; }
.secret-grid { position: relative; display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; }
.secret-grid .sel-shot:hover { outline: 2px solid #6fdc3c; outline-offset: 2px; }
.secret-grid .sel-play { background: #6fdc3c; }
@media (max-width: 991.98px) { .secret-grid { grid-template-columns: repeat(4, 1fr); } }
@media (prefers-reduced-motion: reduce) { .secret.open, .secret-title::before, .secret-title::after { animation: none; } }
/* Roster: every character is a thin slanted slice in one row, so they all fit with nothing to scroll.
   The picked one opens up wide and lights up (hovering picks, so sliding along the row flips through them). */
.sel-roster { display: flex; gap: 6px; margin-top: 28px; padding: 10px 8px 12px; }
.sel-pick { position: relative; flex: 1 1 0; min-width: 0; height: 150px; padding: 0; border: 0; overflow: hidden; background: var(--panel); transform: skewX(-10deg); outline: 2px solid transparent; outline-offset: 2px; transition: flex-grow .4s cubic-bezier(.2,.8,.2,1), transform .2s, outline-color .2s; cursor: pointer; }
.sel-pick.on { flex-grow: 5; outline-color: var(--accent); transform: skewX(-10deg) translateY(-6px); }
.sel-pick img { position: absolute; top: 0; left: -16px; width: calc(100% + 32px); height: 100%; object-fit: cover; transform: skewX(10deg); filter: grayscale(.85) brightness(.6); transition: filter .25s; }
.sel-pick:hover img, .sel-pick.on img { filter: none; }
.sel-pick-name { position: absolute; left: 10px; right: 6px; bottom: 7px; transform: skewX(10deg); font-size: .72rem; line-height: 1.15; letter-spacing: .06em; white-space: nowrap; text-align: left; text-transform: uppercase; color: #fff; text-shadow: 0 1px 4px rgba(0, 0, 0, .9); opacity: 0; transition: opacity .15s; }
.sel-pick.on .sel-pick-name { opacity: 1; transition: opacity .25s .2s; }
.sel-pick.on::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 4px; background: var(--accent); }
.sel-pick:focus-visible { outline-color: #fff; }
@media (max-width: 767.98px) {
  .sel-top { grid-template-columns: 1fr; gap: 18px; }
  .sel-stage { height: clamp(340px, 58vh, 520px); }
  .sel-shots { grid-template-columns: repeat(4, 1fr); }
  /* Roster goes on top so switching character doesn't mean scrolling past the shots. Slices would be too thin
     to tap on a phone, so it's two rows of seven instead; names hide (the big name says who it is) */
  #shootGroups { display: flex; flex-direction: column; }
  .sel-roster { order: -1; display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px 7px; margin: 0 0 12px; padding: 8px 6px 10px; }
  .sel-pick { height: 62px; }
  .sel-pick-name { display: none; }
}

.tile { position: relative; display: block; width: 100%; padding: 0; border: 0; aspect-ratio: 4 / 5; overflow: hidden; background: var(--panel); color: var(--bs-body-color); text-align: left; cursor: pointer; }
.tile img, .tile .ph { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .7s cubic-bezier(.2,.7,.2,1), filter .5s; filter: grayscale(.25); }
.tile:hover img, .tile:focus-visible img { transform: scale(1.05); filter: none; }
.tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Halftone dots fade up from the bottom on hover */
.tile::after { content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0; transition: opacity .35s; background-image: var(--halftone); background-size: 6px 6px; -webkit-mask-image: linear-gradient(0deg, #000 0%, transparent 60%); mask-image: linear-gradient(0deg, #000 0%, transparent 60%); }
.tile:hover::after, .tile:focus-visible::after { opacity: 1; }
.tile .info { position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; padding: 40px 12px 12px; background: linear-gradient(transparent, rgba(0,0,0,.75)); }
.tile .info small { font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); }
.tile .info h3 { font-family: inherit; font-weight: 700; font-size: .85rem; margin: 2px 0 0; }
.tile .badge-video { position: absolute; top: 10px; right: 10px; z-index: 3; background: var(--accent); color: #000; border-radius: 0; font-weight: 700; }

/* Placeholder art until real photos are added */
.ph { display: flex; align-items: center; justify-content: center; }
.ph span { font-family: var(--display); font-size: 3rem; color: rgba(255,255,255,.15); }

/* Reveal on scroll */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity .7s ease, transform .7s ease; }
.reveal.in { opacity: 1; transform: none; }

/* ---------- Edits: a mosaic of every edit ---------- */
.edits { padding: 72px 0 56px; }
.edits-wrap { padding: 0 22px; }
.edits-mosaic { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: clamp(100px, min(13vw, 22vh), 230px); grid-auto-flow: dense; gap: 10px; }
@media (max-width: 575.98px) { .edits-mosaic { grid-template-columns: repeat(3, 1fr); grid-auto-rows: 30vw; gap: 6px; } }
.edit-tile { position: relative; padding: 0; border: 0; overflow: hidden; background: var(--panel); cursor: pointer; transition: transform .35s cubic-bezier(.2,.8,.2,1), filter .35s; }
.edit-tile.big { grid-column: span 2; grid-row: span 2; }
.edit-tile.tall { grid-row: span 2; }
.edit-tile.wide { grid-column: span 2; }
.edit-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .6s cubic-bezier(.2,.7,.2,1); }
/* Halftone dots cover the tiles that aren't in focus */
.edit-tile::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .35s; background-image: var(--halftone); background-size: 5px 5px; }
.edits-mosaic.focusing .edit-tile:not(.on) { filter: grayscale(1) brightness(.5); }
.edits-mosaic.focusing .edit-tile:not(.on)::after { opacity: 1; }
@media (hover: none) {
  .edits-mosaic.focusing .edit-tile:not(.on) { filter: none; }
  .edits-mosaic.focusing .edit-tile:not(.on)::after { opacity: 0; }
}
.edit-tile.on { z-index: 2; transform: scale(1.04); outline: 2px solid var(--accent); outline-offset: 3px; }
.edit-tile.on img { transform: scale(1.07); }
.edit-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Tiles pop in one after another when the section comes into view (uses `translate`, so hover `transform` still works) */
.edit-tile { opacity: 0; translate: 0 18px; }
.edits.in .edit-tile { animation: tileIn .55s cubic-bezier(.2,1.2,.4,1) calc(var(--i, 0) * 45ms) forwards; }
@keyframes tileIn { to { opacity: 1; translate: 0 0; } }

/* Preview that follows the cursor over the name list */
/* ---------- Build logs ---------- */
.logs-lead { max-width: 52ch; }
/* Builds tabs: Full builds / Props & faceshells, with a slanted yellow block behind the chosen one */
.build-tabs { position: relative; display: inline-flex; gap: 4px; }
.build-tabs-blob { position: absolute; top: 0; bottom: 0; left: 0; width: 0; background: var(--accent); transform: skewX(-12deg); transition: left .45s cubic-bezier(.3,1.35,.4,1), width .45s cubic-bezier(.3,1.35,.4,1); pointer-events: none; }
.build-tab { position: relative; z-index: 1; padding: 10px 20px; border: 0; background: transparent; color: var(--bs-secondary-color); font-size: .8rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; transition: color .2s; cursor: pointer; }
.build-tab:hover { color: #fff; }
.build-tab.on { color: var(--ink); }
.build-tab:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
#logs [role="tabpanel"][hidden] { display: none !important; }   /* beats Bootstrap's d-grid */
/* Builds: big slanted panels with the finished costume. Hovering plays a time-lapse of the build
   (script.js): frames flip over the finished photo, the chapter shows in the corner, a bar fills. */
#logList { gap: 34px !important; }
.bx { position: relative; }
.bx-media { position: relative; height: clamp(340px, 62vh, 620px); overflow: hidden; background: var(--ink); clip-path: polygon(3% 0, 100% 0, 97% 100%, 0 100%); }
.bx.has-lapse .bx-media { cursor: pointer; }
.bx-fin, .bx-frame { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; -webkit-user-drag: none; }
.bx-fin { transition: transform 1.2s cubic-bezier(.2,.7,.2,1); }
.bx:hover .bx-fin { transform: scale(1.03); }
.bx-frame { opacity: 0; filter: contrast(1.05) saturate(.9); transition: opacity .38s ease; }
.bx-frame.on { opacity: 1; }
/* Darken the bottom-left so the text reads over any photo */
.bx-media::after { content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none; background: linear-gradient(to top, rgba(7, 7, 8, .9), rgba(7, 7, 8, .35) 45%, transparent 70%); }
.bx-chap { position: absolute; z-index: 3; top: 18px; left: 6%; padding: 4px 10px; background: var(--accent); color: var(--ink); font-size: .7rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; transform: skewX(-10deg); opacity: 0; pointer-events: none; transition: opacity .3s; }
.bx.playing .bx-chap { opacity: 1; }
.bx-bar { position: absolute; z-index: 3; left: 0; right: 0; bottom: 0; height: 4px; background: rgba(255, 255, 255, .12); pointer-events: none; }
.bx-bar span { display: block; width: 0; height: 100%; background: var(--accent); transition: width .46s linear; }
.bx-hint { position: absolute; z-index: 3; top: 18px; right: 6%; padding: 4px 10px; border: 1px solid rgba(255, 255, 255, .35); color: rgba(255, 255, 255, .8); font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; pointer-events: none; transition: opacity .25s; }
.bx.playing .bx-hint { opacity: 0; }.bx-text { position: absolute; z-index: 4; left: 6%; right: 8%; bottom: 7%; max-width: 52ch; pointer-events: none; }
.bx-text a, .bx-text button { pointer-events: auto; }
.bx-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 0 0 6px; font-size: .74rem; letter-spacing: .1em; text-transform: uppercase; color: rgba(255, 255, 255, .75); }
.bx-from { color: var(--accent); }
.bx-status { padding: 2px 8px; background: var(--accent); color: var(--ink); font-weight: 700; }
.bx-name { margin: 0 0 10px; font-family: var(--display); font-size: clamp(2.6rem, 7vw, 6.4rem); line-height: .86; text-transform: uppercase; text-shadow: 0 4px 30px rgba(0, 0, 0, .6); }
.bx-desc { margin: 0 0 14px; max-width: 46ch; color: rgba(255, 255, 255, .82); }
.bx-soon { margin: 0; color: rgba(255, 255, 255, .55); font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; }
/* Props: the same panels, a bit shorter, side by side (one alone fills the row) */
.prop-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 28px; }
.prop-grid .bx-media { height: clamp(320px, 50vh, 500px); }
.prop-grid .bx-name { font-size: clamp(2.2rem, 5vw, 4.4rem); }
/* Phones: the builds stack like cards. Each pins below the menu; the one underneath shrinks back and
   darkens as the next covers it (script.js sets --cover and plays the card on top) */
@media (max-width: 767.98px) {
  #logList.m-stack { display: block !important; }
  #logList.m-stack .bx { position: sticky; top: 64px; margin-bottom: 22vh; transform-origin: 50% 0; transform: scale(calc(1 - var(--cover, 0) * .1)); filter: brightness(calc(1 - var(--cover, 0) * .55)); }
  #logList.m-stack .bx:last-child { margin-bottom: 0; }
  #logList.m-stack .bx-media { height: 70svh; }
}
/* Zigzag (computers): builds alternate left and right and overlap a little; the text sits in the open
   space beside each panel and the huge name breaks out across the panel's edge */
@media (min-width: 768px) {
  #logList { gap: 0 !important; }
  #logList .bx { display: grid; grid-template-columns: 64fr 36fr; align-items: center; }
  #logList .bx + .bx { margin-top: -56px; }
  #logList .bx-media { grid-column: 1; grid-row: 1; height: clamp(360px, 60vh, 600px); }
  #logList .bx-media::after { background: linear-gradient(to left, rgba(7, 7, 8, .6), transparent 40%); }
  #logList .bx-text { position: relative; grid-column: 2; grid-row: 1; left: auto; right: auto; bottom: auto; max-width: none; padding-left: 34px; }
  #logList .bx-name { margin-left: -46%; font-size: clamp(3rem, 7.4vw, 7.4rem); }
  #logList .bx:nth-child(even) { grid-template-columns: 36fr 64fr; }
  #logList .bx:nth-child(even) .bx-media { grid-column: 2; }
  #logList .bx:nth-child(even) .bx-media::after { background: linear-gradient(to right, rgba(7, 7, 8, .6), transparent 40%); }
  #logList .bx:nth-child(even) .bx-text { grid-column: 1; padding: 0 34px 0 0; text-align: right; }
  #logList .bx:nth-child(even) .bx-name { margin: 0 -46% 10px 0; }
  #logList .bx:nth-child(even) .bx-meta { justify-content: flex-end; }
  #logList .bx:nth-child(even) .bx-desc { margin-left: auto; }
  #logList .bx:nth-child(even) .bx-chap { left: auto; right: 6%; }
  #logList .bx:nth-child(even) .bx-hint { right: auto; left: 6%; }
}
@media (max-width: 767.98px) {
  .bx-media { height: 66svh; clip-path: polygon(4% 0, 100% 0, 96% 100%, 0 100%); }
  .bx-text { left: 7%; right: 7%; bottom: 6%; }
  .bx-desc { font-size: .9rem; }
  .prop-grid { grid-template-columns: 1fr; }
  .build-tab { padding: 9px 14px; font-size: .72rem; }
}

/* ---------- About ---------- */
.about-photo { position: relative; aspect-ratio: 4 / 5; background: var(--panel); background-size: cover; background-position: center; }
.about-photo::after { content: ""; position: absolute; inset: 0; background-image: var(--halftone); background-size: 7px 7px; -webkit-mask-image: linear-gradient(20deg, #000, transparent 45%); mask-image: linear-gradient(20deg, #000, transparent 45%); }

/* ---------- Contact ---------- */
.contact-title { font-size: clamp(2.4rem, 8vw, 6.4rem); }
.contact-title mark { padding: 0 .12em; }
.contact-lead { max-width: 46ch; color: var(--bs-secondary-color); }

/* ---------- Footer ---------- */
.site-footer { padding: 22px 0; border-top: 1px solid var(--line); color: var(--bs-secondary-color); font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; }
.site-footer a { color: var(--bs-secondary-color); }
.site-footer a:hover { color: var(--accent); }

/* ---------- Viewer (full screen, select-screen style) ---------- */
.lb .modal-dialog { transform: none !important; }   /* no Bootstrap slide-down; the shot does its own entrance */
.lb-content { position: relative; overflow: hidden; background: #070708; border: 0; border-radius: 0; }
/* The shot itself, blurred and darkened, fills the screen so every photo sets its own mood */
.lb-back { position: absolute; inset: -60px; background-size: cover; background-position: center; filter: blur(40px) brightness(.32) saturate(1.3); transform: scale(1.1); transition: background-image .4s; }
.lb-back::after { content: ""; position: absolute; inset: 0; background-image: var(--halftone); background-size: 6px 6px; opacity: .35; }
.lb-bigname { position: absolute; left: 0; right: 0; top: 50%; z-index: 1; margin: 0; transform: translateY(-50%); font-family: var(--display); font-size: clamp(3rem, 13vw, 13rem); line-height: .85; text-align: center; text-transform: uppercase; text-wrap: balance; color: transparent; -webkit-text-stroke: 1.5px rgba(255, 210, 63, .35); pointer-events: none; }
.lb-info { position: absolute; z-index: 3; top: 22px; left: 26px; max-width: 34ch; pointer-events: none; }
.lb-cat { margin: 0 0 2px; color: var(--accent); font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; }
.lb-count { margin: 0; font-family: var(--display); font-size: clamp(2.2rem, 4vw, 3.4rem); line-height: 1; }
.lb-total { color: rgba(255, 255, 255, .35); font-size: .45em; vertical-align: .55em; }
.lb-title { margin: 6px 0 0; font-family: var(--body, inherit); font-size: .8rem; font-weight: 400; letter-spacing: .06em; text-transform: uppercase; color: rgba(255, 255, 255, .7); }
.lb-desc { margin: 4px 0 0; font-size: .8rem; color: rgba(255, 255, 255, .6); }
/* The shot: whole and uncropped, on a slanted yellow panel peeking out behind it */
.lb-stage { position: absolute; z-index: 2; inset: 96px 100px 118px; display: flex; align-items: center; justify-content: center; touch-action: pan-y; }
.lb-media { position: relative; display: flex; align-items: center; justify-content: center; max-width: 100%; max-height: 100%; }
.lb-media::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--accent); transform: translate(14px, 14px) skewX(-6deg); opacity: .9; }
.lb-media img, .lb-media video { display: block; max-width: 100%; max-height: calc(100vh - 214px); object-fit: contain; box-shadow: 0 30px 70px rgba(0, 0, 0, .7); }
.lb-media iframe { width: min(1100px, 100vw - 200px); aspect-ratio: 16 / 9; border: 0; display: block; }
.lb-media .ph { width: min(900px, 80vw); aspect-ratio: 16 / 10; max-height: 70vh; }
/* Big slanted arrow panels at the sides */
.lb-nav { position: absolute; z-index: 3; top: 50%; width: 56px; height: 150px; margin-top: -75px; display: grid; place-items: center; padding: 0; border: 0; background: rgba(255, 255, 255, .06); color: #fff; transform: skewX(-10deg); transition: background-color .2s, color .2s; cursor: pointer; }
.lb-nav.prev { left: 22px; } .lb-nav.next { right: 22px; }
.lb-nav svg { width: 26px; height: 26px; transform: skewX(10deg); fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: square; transition: transform .2s; }
.lb-nav:hover, .lb-nav:focus-visible { background: var(--accent); color: var(--ink); }
.lb-nav.prev:hover svg { transform: skewX(10deg) translateX(-4px); }
.lb-nav.next:hover svg { transform: skewX(10deg) translateX(4px); }
.lb-nav:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
/* Strip of every shot along the bottom (slides to keep the current one in the middle) */
.lb-strip { position: absolute; z-index: 3; left: 0; right: 0; bottom: 18px; height: 80px; overflow: hidden; -webkit-mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent); mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent); }
.lb-strip-in { position: absolute; top: 8px; left: 50%; display: flex; gap: 8px; transition: transform .45s cubic-bezier(.2,.8,.2,1); }
.lb-thumb { position: relative; flex: 0 0 48px; height: 64px; padding: 0; border: 0; overflow: hidden; background: var(--panel); transform: skewX(-10deg); outline: 2px solid transparent; outline-offset: 2px; opacity: .45; transition: opacity .2s, transform .2s, outline-color .2s; cursor: pointer; }
.lb-thumb img { position: absolute; top: 0; left: -8px; width: calc(100% + 16px); height: 100%; object-fit: cover; transform: skewX(10deg); }
.lb-thumb:hover { opacity: .85; }
.lb-thumb.on { opacity: 1; outline-color: var(--accent); transform: skewX(-10deg) translateY(-6px); }
.lb-thumb.is-video::after { content: ""; position: absolute; right: 4px; bottom: 4px; border-style: solid; border-width: 5px 0 5px 8px; border-color: transparent transparent transparent var(--accent); }
.lb-close { position: absolute; z-index: 4; top: 18px; right: 18px; width: 44px; height: 44px; padding: 0; background-color: var(--accent); background-size: 14px; border-radius: 0; opacity: 1; filter: none; }
.lb-close:hover { opacity: .85; }
@media (max-width: 767.98px) {
  .lb-info { top: 14px; left: 16px; right: 70px; }
  .lb-stage { inset: 92px 22px 100px 10px; }   /* a little more room on the right for the yellow panel */
  .lb-media img, .lb-media video { max-height: calc(100svh - 192px); }
  .lb-media::before { transform: translate(8px, 8px) skewX(-6deg); }
  .lb-media iframe { width: calc(100vw - 20px); }
  .lb-nav { display: none; }   /* swipe, or tap the strip */
  .lb-strip { bottom: 10px; height: 74px; }
  .lb-thumb { flex-basis: 40px; height: 56px; }
}

@media (max-width: 575.98px) {
  .section { padding: 80px 0; }
  .tile .info h3 { font-size: .78rem; }
}

/* ---------- Polish ---------- */
/* Photos uncover from the bottom as they scroll into view */
.row > .reveal .tile { clip-path: inset(100% 0 0 0); transition: clip-path 1s cubic-bezier(.7,0,.2,1), transform .25s ease-out; }
.row > .reveal.in .tile { clip-path: inset(0 0 0 0); }
.about-photo.reveal { opacity: 1; transform: none; clip-path: inset(100% 0 0 0); transition: clip-path 1.2s cubic-bezier(.7,0,.2,1); }
.about-photo.reveal.in { clip-path: inset(0 0 0 0); }

/* Custom cursor (computers with a mouse): a dot that follows exactly and a ring that trails behind,
   growing over anything you can click */
.cursor-dot, .cursor-ring { position: fixed; left: 0; top: 0; z-index: 3600; pointer-events: none; border-radius: 50%; opacity: 0; }
.cursor-dot { width: 6px; height: 6px; margin: -3px 0 0 -3px; background: var(--accent); transition: opacity .3s; }
.cursor-ring { width: 34px; height: 34px; margin: -17px 0 0 -17px; border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent); transition: opacity .3s, width .25s, height .25s, margin .25s, background-color .25s, border-color .25s; }
.cursor-ring.big { width: 62px; height: 62px; margin: -31px 0 0 -31px; background: color-mix(in srgb, var(--accent) 10%, transparent); border-color: var(--accent); }
html.has-cursor .cursor-dot, html.has-cursor .cursor-ring { opacity: 1; }
html.has-cursor, html.has-cursor a, html.has-cursor button, html.has-cursor .intro-screen { cursor: none; }

/* ============================================================
   ANIMATIONS
   ============================================================ */
.d1 { --d: .1s; } .d2 { --d: .25s; } .d3 { --d: .45s; }
.intro { opacity: 0; transform: translateY(14px); animation: fadeUp .8s ease var(--d, 0s) forwards; }
@keyframes fadeUp { to { opacity: 1; transform: none; } }

/* Faint film grain over the page */
.grain {
  position: fixed; inset: -50%; z-index: 1500; pointer-events: none; opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain .9s steps(6) infinite;
}
@keyframes grain {
  0% { transform: translate(0, 0); } 20% { transform: translate(-5%, 3%); } 40% { transform: translate(4%, -6%); }
  60% { transform: translate(-3%, 5%); } 80% { transform: translate(6%, 2%); } 100% { transform: translate(0, 0); }
}
/* Phones: the moving grain layer (twice the screen each way, blended over everything every frame) and the
   menu's background blur (redone every frame while the photo behind it moves) made scrolling stutter. Still,
   screen-sized grain and a solid menu look the same at phone size and cost next to nothing */
@media (hover: none), (max-width: 767.98px) {
  .grain { inset: 0; animation: none; }
  /* The flying photo's changing filter and big soft shadow were redrawn every frame; fast scrolling outran it */
  .flyer { box-shadow: none; }
  .flyer-photo { filter: none; }
  .site-nav.scrolled { background: rgba(14, 14, 16, .97); backdrop-filter: none; -webkit-backdrop-filter: none; }
}

/* Reading-progress bar */
.scroll-progress { position: fixed; top: 0; left: 0; height: 2px; width: 100%; z-index: 1100; background: var(--accent); transform-origin: 0 50%; transform: scaleX(var(--p, 0)); }

/* Tiles tilt toward the cursor (JS sets --rx/--ry) */
.tile { transition: transform .25s ease-out; }
.tile.tilting { transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); }

/* ---------- Opening: TSG traced as an outline, filled, then drained into the hero (JS drives it) ---------- */
.intro-screen { display: none; }
html.show-intro { overflow: hidden; }
html.show-intro .intro-screen {
  display: block; position: fixed; inset: 0; z-index: 3000; cursor: pointer; background: var(--ink);
  animation: introDone 0s linear 5s forwards; /* failsafe: gone even if JS never runs */
}
@keyframes introDone { to { visibility: hidden; pointer-events: none; } }
.intro-screen.out { opacity: 0; transition: opacity .35s ease; }
.intro-hint { position: absolute; bottom: 22px; left: 22px; margin: 0; font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--bs-secondary-color); }
.intro-svg { position: absolute; fill: var(--accent); stroke: var(--accent); font-family: var(--display); pointer-events: none; }
/* The page's own entrance waits for the intro */
html.show-intro .intro { animation-delay: calc(var(--d, 0s) + 2.1s); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .grain { animation: none; }
  .intro { animation: none; opacity: 1; transform: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .row > .reveal .tile, .about-photo.reveal { clip-path: none; }
  .edit-tile { opacity: 1; translate: none; animation: none !important; }
  .tile.tilting { transform: none; }
  .hero { height: auto; }
  .hero-stage { position: relative; }
}

/* Colour tester (only shown with ?colors in the address) */
.color-tester {
  position: fixed; right: 16px; bottom: 16px; z-index: 3500; display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  max-width: calc(100vw - 32px); padding: 8px; background: rgba(14, 14, 16, .92); border: 1px solid var(--line);
}
.color-tester button { width: 26px; height: 26px; padding: 0; border: 1px solid rgba(255, 255, 255, .25); }
.color-tester button.on { outline: 2px solid #fff; outline-offset: 2px; }
.color-tester span { margin-left: 6px; font-size: .7rem; letter-spacing: .1em; text-transform: uppercase; white-space: nowrap; }

/* ============================================================
   BUILD PAGES (helldiver.html): big finished photo, quick facts,
   then numbered chapters with text on the left and photos on the right
   ============================================================ */
.build-back { font-size: .78rem; letter-spacing: .14em; text-transform: uppercase; color: var(--bs-body-color); }
.build-back:hover { color: var(--accent); }
.build-hero { position: relative; height: 92svh; min-height: 520px; overflow: hidden; }
.build-hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
.build-hero::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(14,14,16,.2) 40%, var(--ink) 98%); }
.build-hero-text { position: absolute; left: 0; right: 0; bottom: 6vh; z-index: 1; }
.build-title { margin: 0; font-family: var(--display); font-size: clamp(3rem, 12vw, 9rem); line-height: .9; text-transform: uppercase; }
.build-lead { max-width: 560px; margin: 14px 0 0; color: var(--bs-body-color); }
.build-facts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; margin-top: 30px; background: var(--line); border: 1px solid var(--line); }
.build-facts div { padding: 16px 18px; background: var(--ink); }
@media (max-width: 991.98px) { .build-facts { grid-template-columns: 1fr 1fr; } }
.build-facts strong { display: block; margin-bottom: 4px; font-size: .7rem; letter-spacing: .14em; text-transform: uppercase; color: var(--accent); }
.chapter { display: grid; grid-template-columns: minmax(220px, 1fr) 2.2fr; gap: 12px 40px; padding: 70px 0; border-bottom: 1px solid var(--line); }
.chapter-text { position: sticky; top: 90px; align-self: start; grid-row: 1 / span 2; }
.chapter-num { margin: 0 0 6px; font-size: .78rem; letter-spacing: .14em; color: var(--accent); }
.chapter h2 { font-family: var(--display); font-size: clamp(1.8rem, 3.4vw, 2.8rem); text-transform: uppercase; }
.chapter-text h2 + p { color: var(--bs-secondary-color); max-width: 34ch; }
.chapter-count { margin: 18px 0 0; font-size: .7rem; letter-spacing: .14em; text-transform: uppercase; color: var(--bs-secondary-color); }
/* Six-column photo grid: normal tiles take 2 columns, "half" 3, "wide" all 6, "big" 4 columns and 2 rows.
   Dense packing lets smaller tiles fill the gaps next to a big one. */
.chapter-photos { display: grid; grid-template-columns: repeat(6, 1fr); grid-auto-flow: dense; gap: 12px; }
.shot { position: relative; display: block; grid-column: span 2; aspect-ratio: 4 / 5; overflow: hidden; background: var(--panel); }
.shot.half { grid-column: span 3; aspect-ratio: 4 / 3; }
.shot.wide { grid-column: span 6; aspect-ratio: 16 / 9; }
.shot.big { grid-column: span 4; grid-row: span 2; aspect-ratio: auto; }
.shot.solo { grid-column: span 4; }
.shot img { width: 100%; height: 100%; object-fit: cover; transition: transform .7s cubic-bezier(.2,.7,.2,1); }
.shot.wide img, .shot.sketch img { object-fit: contain; }
.shot.sketch, .shot.sketch img { background: #fff; }
.shot.wide.fill img { object-fit: cover; }   /* a leftover photo stretched across the row */
.shot:hover img { transform: scale(1.04); }
.shot:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Clips: short muted videos in a sideways-scrolling strip under the photos, playing while they are on screen */
.chapter-clips { grid-column: 2; display: grid; grid-auto-flow: column; grid-auto-columns: calc((100% - 24px) / 3); gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: thin; padding-bottom: 8px; }
.clip { position: relative; display: block; aspect-ratio: 9 / 16; overflow: hidden; background: var(--panel); scroll-snap-align: start; }
.clip video { display: block; width: 100%; height: 100%; object-fit: cover; }
.clip::after { content: "\25B6  Clip"; position: absolute; left: 8px; bottom: 6px; font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; color: #fff; text-shadow: 0 1px 4px rgba(0, 0, 0, .8); }
.clip:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Photos and clips wipe in as each chapter scrolls into view */
.chapter .shot, .chapter .clip { clip-path: inset(100% 0 0 0); transition: clip-path 1s cubic-bezier(.7,0,.2,1); }
.chapter.in .shot, .chapter.in .clip { clip-path: inset(0 0 0 0); }
.chapter.in .shot:nth-child(2) { transition-delay: .1s; } .chapter.in .shot:nth-child(3) { transition-delay: .2s; } .chapter.in .shot:nth-child(4) { transition-delay: .3s; }
.build-end { padding: 50px 0 80px; margin: 0; }
/* Build pages show the same viewer as the main site, in a full-screen <dialog> instead of a Bootstrap modal */
.lb-dialog { position: fixed; inset: 0; width: 100vw; height: 100vh; height: 100dvh; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: #070708; color: var(--bs-body-color); }
.lb-dialog::backdrop { background: #000; }
.lb-dialog .lb-content { width: 100%; height: 100%; }
@media (max-width: 767.98px) {
  .chapter { grid-template-columns: 1fr; gap: 18px; padding: 48px 0; }
  .chapter-text { position: static; grid-row: auto; }
  .chapter-photos { grid-template-columns: 1fr 1fr; }
  .chapter-clips { grid-column: 1; grid-auto-columns: 44%; }
  .shot, .shot.half { grid-column: span 1; aspect-ratio: 4 / 5; }
  .shot.wide { grid-column: span 2; }
  .shot.big, .shot.solo { grid-column: span 2; grid-row: auto; aspect-ratio: 4 / 5; }
}
@media (prefers-reduced-motion: reduce) {
  .chapter .shot, .chapter .clip { clip-path: none; transition: none; }
}
