/* ================================
   Travis Hurlock — Portfolio
   ================================ */

:root{
  --bg:#0a0b0f;
  --bg-alt:#111319;
  --surface:#171a22;
  --surface-2:#1d212b;
  --border:#272c38;
  --text:#f2f1ee;
  --text-dim:#9aa0ad;
  --text-faint:#666d7d;
  --accent:#ff5a3c;
  --accent-2:#E5FF53;
  /* Lighter reading tone for the longer-form copy on individual project
     pages — the standard --text-dim is already ~7:1+ against --bg, this is
     a further, deliberate perceptual bump for extended reading, not a
     contrast fix. Scoped to .proj-main/.proj-status only; homepage
     work-item copy keeps --text-dim. */
  --text-body:#adb3c0;
  --navy:#1c2b4a;
  --red:#c41e3a;
  --bone:#f5f0e8;
  --radius:14px;
  --maxw:1180px;
  --font:'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
body{
  margin:0;
  font-family:var(--font);
  background:var(--bg);
  color:var(--text);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
h1,h2,h3,h4{ margin:0; font-weight:700; letter-spacing:-0.02em; }
p{ margin:0; }
ul{ margin:0; padding:0; list-style:none; }
button{ font-family:inherit; cursor:pointer; }
.container{ max-width:var(--maxw); margin:0 auto; padding:0 32px; }
.reveal{ opacity:0; transform:translateY(24px); transition:opacity .7s ease, transform .7s ease; }
.reveal.is-visible{ opacity:1; transform:translateY(0); }
[data-depth]{ --scroll-depth:0px; transform:translate3d(0,var(--scroll-depth),0); }
.reveal--project{ transform:translateY(16px); transition-duration:.6s; }
.reveal--green-rule{ position:relative; padding-left:24px; }
.reveal--green-rule::before{
  content:''; position:absolute; left:0; top:0; bottom:0; width:2px; border-radius:2px;
  background:linear-gradient(180deg,var(--accent-2),rgba(229,255,83,.14));
  transform:scaleY(.28); transform-origin:top; opacity:.45;
  transition:transform .7s ease .12s, opacity .7s ease .12s;
}
.reveal--green-rule.is-visible::before{ transform:scaleY(1); opacity:1; }

/* ---------- Page loader ---------- */
html.is-loading{ overflow:hidden; }
.loader{
  position:fixed; inset:0; z-index:9999; display:flex; align-items:center; justify-content:center;
  background:#08090c; transition:opacity .35s ease, visibility .35s ease;
}
.loader.is-hidden{ opacity:0; visibility:hidden; pointer-events:none; }

.loader__stage{ position:relative; width:320px; height:320px; display:flex; align-items:center; justify-content:center; }
.loader__slate{ position:absolute; inset:0; }
.loader__slate svg{ width:100%; height:100%; }

.loader__spot{ animation:loaderSpotTravel 2.7s linear infinite; }
@keyframes loaderSpotTravel{
  0%   { transform:translate(0px,0px); }
  25%  { transform:translate(180px,0px); }
  50%  { transform:translate(180px,180px); }
  75%  { transform:translate(0px,180px); }
  100% { transform:translate(0px,0px); }
}

.loader__bloom{
  position:absolute; width:80px; height:80px; margin:-40px 0 0 -40px; border-radius:50%;
  background:radial-gradient(circle, rgba(255,255,255,0.5) 0%, rgba(255,255,255,0.22) 35%, transparent 75%);
  filter:blur(10px); mix-blend-mode:screen; animation:loaderTravelOuter 2.7s linear infinite; pointer-events:none;
}
@keyframes loaderTravelOuter{
  0%   { left:21.875%; top:21.875%; }
  25%  { left:78.125%; top:21.875%; }
  50%  { left:78.125%; top:78.125%; }
  75%  { left:21.875%; top:78.125%; }
  100% { left:21.875%; top:21.875%; }
}

.loader__orb{
  position:relative; width:180px; height:180px; border-radius:9px;
  clip-path:inset(0 round 9px); -webkit-clip-path:inset(0 round 9px);
}
.loader__comet{
  position:absolute; width:10px; height:10px; margin:-5px 0 0 -5px; border-radius:50%; background:#fff;
  filter:blur(1.5px);
  box-shadow:
    0 0 8px 2px rgba(255,255,255,0.75),
    0 0 20px 8px rgba(255,255,255,0.45),
    0 0 40px 16px rgba(255,255,255,0.26),
    0 0 70px 26px rgba(255,255,255,0.12);
  animation:loaderTravel 2.7s linear infinite;
}
@keyframes loaderTravel{
  0%   { left:0%;   top:0%; }
  25%  { left:100%; top:0%; }
  50%  { left:100%; top:100%; }
  75%  { left:0%;   top:100%; }
  100% { left:0%;   top:0%; }
}
.loader__frame{ position:absolute; inset:0; border-radius:9px; border:2.5px solid rgba(255,255,255,0.1); }
.loader__panel{
  position:absolute; inset:2.5px; border-radius:8px; background:#08090c;
  display:flex; align-items:center; justify-content:center;
}
.loader__panel svg{
  width:104px; height:auto; opacity:0; transform:scale(0.88);
  animation:loaderMarkIn 0.6s cubic-bezier(0.2,0.8,0.2,1) forwards; animation-delay:0.15s;
}
@keyframes loaderMarkIn{ to{ opacity:1; transform:scale(1); } }

/* ---------- Nav ---------- */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:100;
  padding:20px 0;
  background:rgba(10,11,15,0.7);
  backdrop-filter:blur(10px);
  border-bottom:1px solid transparent;
  transition:border-color .3s ease, background .3s ease;
}
.nav.scrolled{ border-bottom-color:var(--border); background:rgba(10,11,15,0.92); }
/* Same max-width + auto-margin + 32px padding as .container, so this row's
   left/right edges land exactly where the page copy's do, at any width. */
.nav__inner{
  display:flex; align-items:center; justify-content:space-between;
  max-width:var(--maxw); margin:0 auto; width:100%; padding:0 32px;
}
/* SVG mark nearly bleeds to the bar's top/bottom without changing the bar's
   own height: it's taller than the row's normal content box, then pulled
   back to that same box height with matching negative margins, so it can't
   grow .nav__inner's (and therefore .nav's) cross-axis size. */
.nav__mark{ display:flex; align-items:center; color:var(--text); }
.nav__mark svg{ height:48px; width:auto; display:block; margin:-11px 0; }
/* Explicit, on-brand focus treatment — production relies on the browser's
   own default ring here, which is faint and inconsistent across browsers;
   that omission shouldn't be carried into this prototype as a genuine
   accessibility gap. outline never affects layout, so this can't shift
   anything around it. */
.nav__mark:focus-visible{ outline:2px solid var(--accent-2); outline-offset:4px; border-radius:4px; }
.nav__links{ display:flex; gap:28px; align-items:center; }
.nav__links a{ font-size:14px; color:var(--text-dim); transition:color .2s ease; }
.nav__links a:hover{ color:var(--text); }
/* Contact and Client Area are plain typographic nav items now — same
   size, weight and spacing as every other link, distinguished only by
   colour (and colour alone isn't the only cue: focus-visible still gets
   a real outline, same as the rest of the nav). No pill background,
   border or extra padding. */
.nav__cta{ font-size:14px; font-weight:600; transition:color .2s ease; }
.nav__cta--primary{ color:var(--accent-2) !important; }
.nav__cta--primary:hover{ color:var(--text) !important; }
.nav__cta--ghost{ color:var(--accent) !important; }
.nav__cta--ghost:hover{ color:var(--text) !important; }
.nav__cta:focus-visible{ outline:2px solid var(--accent-2); outline-offset:3px; border-radius:3px; }
/* Client Area isn't live yet — a non-interactive, muted label rather
   than a link that would 404. Same primary-accent color family, just
   dimmed, so it still reads as "coming" rather than "missing". */
.nav__cta--soon{ opacity:.55; cursor:default; }
.nav__cta-soon-label{ font-weight:400; }

.nav__toggle{ display:none; background:none; border:0; color:var(--text); }
@media (max-width:860px){
  .nav__links{
    position:fixed; inset:0 0 auto 0; top:64px; flex-direction:column; align-items:flex-start;
    background:var(--bg-alt); padding:24px 32px 32px; border-bottom:1px solid var(--border);
    transform:translateY(-120%); transition:transform .35s ease; gap:18px;
  }
  .nav__links.open{ transform:translateY(0); }
  .nav__toggle{ display:block; }
  .nav__cta{ font-size:15px; }
  .nav__links > li{ width:100%; }
}

/* ---------- Hero ---------- */
/* Stage 1.1: the full-bleed autoplaying video background is gone — it
   fought the typography for attention and made the heading feel
   uncontrolled. Two-column composition instead: copy left, a static
   black-glass media stage right, evidence cards spanning beneath both. */
.hero{ position:relative; padding:152px 0 64px; background:var(--bg); }
/* Full-hero ambient video: fills the whole header (behind the fixed,
   semi-transparent nav too, since .hero starts at y:0 under it), a dark
   overlay sits on top of the video only, and the copy/container above
   that keeps the exact same contrast it had against the flat --bg. */
.hero__bg{ position:absolute; inset:0; z-index:0; overflow:hidden; }
.hero__bg-video{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.hero__bg-overlay{ position:absolute; inset:0; background:rgba(10,11,15,0.78); }
.hero .container{ position:relative; z-index:1; }
.hero__grid{
  display:grid; grid-template-columns:1.05fr 0.95fr; gap:56px; align-items:center;
  margin-bottom:56px;
}
@media(max-width:960px){ .hero__grid{ grid-template-columns:1fr; gap:40px; } }

.hero__copy{ max-width:60ch; }
/* Glass utility — used only by the hero evidence cards now, not as a
   full-panel treatment over video. Restrained: fill + edge + one inner
   highlight, no extra blur stacking. */
.glass{
  background:linear-gradient(135deg, rgba(255,255,255,0.10), rgba(255,255,255,0.03));
  border:1px solid rgba(255,255,255,0.14);
  border-radius:14px;
}
.hero__eyebrow{
  display:inline-flex; align-items:center; gap:10px; font-size:12.5px; letter-spacing:0.14em; text-transform:uppercase;
  color:var(--accent-2); font-weight:600; margin-bottom:22px;
}
.hero__eyebrow::before{ content:''; width:7px; height:7px; border-radius:50%; background:var(--accent-2); box-shadow:0 0 12px var(--accent-2); }
.hero h1{
  font-size:clamp(30px, 3.4vw, 46px); line-height:1.14; margin-bottom:18px; max-width:17ch;
  font-weight:800; text-wrap:balance;
}
.hero__tagline{
  font-size:clamp(16px, 1.5vw, 18px); font-weight:600; color:var(--text); opacity:0.92; margin-bottom:14px;
  max-width:62ch; text-wrap:pretty;
}
.hero__sub{
  font-size:16px; color:var(--text-dim); max-width:60ch; margin-bottom:34px; font-weight:400; text-wrap:pretty;
}
.hero__actions{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; }

/* Media stage — an elegant frame, not a fake device. Deep black surface,
   a hairline edge highlight instead of hardware chrome, restrained
   shadow for a slight dimensional lift. The frame/poster structure stays
   generic so a future talking-avatar video only needs a new image src
   (and its own play control re-added) — not a rebuilt hero. */
.hero__media{ position:relative; }
.media-stage{
  position:relative; aspect-ratio:16/10; border-radius:20px; overflow:hidden;
  background:#050506; border:1px solid rgba(255,255,255,0.08);
  box-shadow:0 30px 60px -20px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.06);
}
.media-stage__poster{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:0.88; }
/* Full-bleed portrait fill rather than a small image floating in black
   space — strong, confident crop, face kept well in frame. */
.media-stage__poster--portrait{ opacity:1; object-position:50% 25%; }
.media-stage::after{
  content:''; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(180deg, rgba(0,0,0,0.12) 0%, rgba(0,0,0,0.02) 30%, rgba(0,0,0,0.35) 100%);
}
.media-stage__label{
  position:absolute; top:18px; left:18px; z-index:2; font-size:11px; font-weight:700; letter-spacing:0.08em; text-transform:uppercase;
  color:var(--text); background:rgba(10,11,15,0.55); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,0.14); border-radius:100px; padding:7px 14px;
}
.media-stage__play{
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); z-index:2;
  width:74px; height:74px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:var(--accent); color:#0a0b0f; border:none; cursor:pointer;
  box-shadow:0 8px 28px rgba(255,90,60,0.35);
  transition:transform 200ms cubic-bezier(0.23,1,0.32,1), background 200ms ease, box-shadow 200ms ease;
}
.media-stage__play svg{ width:26px; height:26px; margin-left:3px; }
.media-stage__play:hover{ background:#ff7256; transform:translate(-50%,-50%) scale(1.06); box-shadow:0 10px 34px rgba(255,90,60,0.45); }
.media-stage__play:focus-visible{ outline:2px solid var(--accent-2); outline-offset:4px; }
.btn{
  position:relative; isolation:isolate;
  display:inline-flex; align-items:center; gap:8px; padding:15px 26px; border-radius:100px;
  font-size:14.5px; font-weight:700; border:1px solid transparent;
  transition:transform 160ms cubic-bezier(0.23,1,0.32,1), background 200ms ease, border-color 200ms ease;
  clip-path:inset(0 round 100px); -webkit-clip-path:inset(0 round 100px);
}
.btn--primary{ background:var(--accent); color:#0a0b0f; }
.btn--primary:hover{ background:#ff7256; transform:translateY(-2px); }
.btn--ghost{ background:transparent; color:var(--text); border-color:var(--border); }
.btn--ghost:hover{ border-color:var(--text-dim); transform:translateY(-2px); }
.btn:active{ transform:scale(0.97); }
.btn__play-icon{ color:var(--accent); }

/* Hover: a small comet travels the button's perimeter. clip-path keeps it
   strictly contained to the pill's own rounded shape — this is the exact
   version that worked correctly on screen; later attempts to let the glow
   spill past the edge (removing this clip-path) are what introduced the
   misalignment. Off by default, only runs on hover/focus. */
.btn::before{
  content:''; position:absolute; z-index:0; pointer-events:none;
  width:8px; height:8px; margin:-4px 0 0 -4px; border-radius:50%; background:#fff;
  left:0%; top:0%; opacity:0;
  box-shadow:
    0 0 6px 2px rgba(255,255,255,0.75),
    0 0 16px 6px rgba(255,255,255,0.45),
    0 0 30px 12px rgba(255,255,255,0.22);
  transition:opacity 220ms ease;
  animation:btnComet 2.6s linear infinite paused;
}
.btn:hover::before, .btn:focus-visible::before{ opacity:1; animation-play-state:running; }
.btn--no-comet::before{ content:none; }
@keyframes btnComet{
  0%   { left:0%;   top:0%; }
  25%  { left:100%; top:0%; }
  50%  { left:100%; top:100%; }
  75%  { left:0%;   top:100%; }
  100% { left:0%;   top:0%; }
}

/* Tertiary icon-only hero action (LinkedIn "in" glyph). Deliberately not a
   fourth equal-weight pill: same height/corner family as .btn so it sits
   comfortably in the row, but circular, unlabelled and low-contrast until
   hovered, so it reads as "profile/proof" rather than a fourth CTA competing
   with See how I can help / Play reel / Email me. Text glyph, not
   LinkedIn's brand mark, kept in the site's own palette rather than LinkedIn
   blue, so it stays part of this design system rather than looking like an
   embedded social widget. */
.btn--icon{
  display:inline-flex; align-items:center; justify-content:center;
  width:48px; height:48px; padding:0; border-radius:50%;
  border:1px solid var(--border); background:transparent; color:var(--text-dim);
  font-size:15px; font-weight:700; letter-spacing:-0.02em;
  transition:border-color 200ms ease, color 200ms ease, transform 160ms cubic-bezier(0.23,1,0.32,1);
  clip-path:inset(0 round 50%); -webkit-clip-path:inset(0 round 50%);
}
.btn--icon:hover{ border-color:var(--text-dim); color:var(--text); transform:translateY(-2px); }

/* Four equal evidence signals, not paragraphs — strong numeral scale,
   minimal supporting text. Desktop: four columns. Tablet/mobile: a
   balanced 2×2 (never three-plus-one). */
.hero__stats{ display:grid; grid-template-columns:repeat(4,1fr); gap:12px; }
.hero__stat{ padding:22px 20px 22px; border-radius:14px; border:none; }
.hero__stat .num{ font-size:clamp(26px,3.4vw,36px); font-weight:800; color:var(--text); display:block; margin-bottom:6px; letter-spacing:-0.01em; }
.hero__stat .lbl{ font-size:12px; color:var(--text-faint); line-height:1.35; }
@media (max-width:760px){
  .hero__stats{ grid-template-columns:repeat(2,1fr); gap:10px; }
  .hero__stat{ padding:18px 16px 18px; }
}

/* ---------- Credibility rail: seamless single-line client carousel ---------- */
/* Restored from Stage 1.1's static two-row rail, which wrapped and read
   as broken. Calm, slow, single-line movement, continuous with no pause
   control or hover/focus interaction — runs the same way for every visitor.
   Kept as its own band, separated from #proof below by the normal
   section rhythm — not pulled back up against the Selected Proof
   heading. */
.orgs{ border-top:1px solid var(--border); border-bottom:1px solid var(--border); background:var(--bg-alt); padding:26px 0; overflow:hidden; }
.orgs__wrap{ position:relative; max-width:var(--maxw); margin:0 auto; }
.orgs__label{
  display:block; text-align:center; font-size:11px; font-weight:700;
  letter-spacing:0.14em; text-transform:uppercase; color:var(--text-faint);
  opacity:0.7; margin:0 0 14px;
}
/* --marquee-fade: soft edge dissolve so names entering/leaving the
   viewport fade rather than clip. */
.orgs__wrap{
  --marquee-fade:72px;
  -webkit-mask-image:linear-gradient(to right, transparent 0, #000 var(--marquee-fade), #000 calc(100% - var(--marquee-fade)), transparent 100%);
  mask-image:linear-gradient(to right, transparent 0, #000 var(--marquee-fade), #000 calc(100% - var(--marquee-fade)), transparent 100%);
}
/* No gap on the outer flex: the two groups sit directly side by side.
   Each group carries its own trailing 56px as padding-right (below), so
   its rendered width already equals one full "period" of the loop —
   what makes translateX(-50%) of the doubled track land on an exact
   repeat with no jump, instead of being short by half an inter-group
   gap. */
.marquee{ display:flex; white-space:nowrap; width:max-content; will-change:transform; }
/* Animation is gated behind .is-ready, added by script.js only after the
   duplicate group has been cloned in — so it can never start playing
   against the single-copy width and leave a gap at the loop boundary.
   Slow (70s) so it reads as calm, not distracting. */
.marquee.is-ready{ animation:scrollx 70s linear infinite; }
.marquee__group{ display:flex; gap:56px; padding-right:56px; white-space:nowrap; align-items:center; }
.marquee span{ font-size:15px; font-weight:600; color:var(--text-faint); letter-spacing:0.02em; white-space:nowrap; }
/* Client logos: the source PNGs are pre-baked solid white (see
   assets/img/logos/) rather than recoloured live via CSS filter — 62
   images (31 plus their clone for the seamless loop) animating at once
   with a per-frame filter was real GPU cost, not just perceived
   slowness, especially on mobile. Opacity-only now: cheap, GPU-friendly,
   same 75%-at-rest / full on hover behaviour. Fixed height / auto width
   keeps each mark's own proportions while giving the row one consistent
   rhythm. */
.marquee img{
  height:28px;
  width:auto;
  max-width:140px;
  object-fit:contain;
  opacity:0.75;
  transition:opacity .25s ease;
}
.marquee img:hover{ opacity:1; }
@media(max-width:760px){ .marquee img{ height:22px; max-width:110px; } }
@keyframes scrollx{ from{ transform:translateX(-50%); } to{ transform:translateX(0%); } }
/* Holds still on hover/keyboard focus — no visible control, just a
   passive courtesy so the row doesn't keep moving under your cursor
   while you're looking at it. */
.orgs__wrap:hover .marquee,
.orgs__wrap:focus-within .marquee{ animation-play-state:paused; }
@media(max-width:760px){ .orgs__wrap{ --marquee-fade:32px; } }

/* ---------- Section shared ---------- */
/* One spacing system for the whole page: ~136px desktop, ~96px tablet,
   ~80px mobile — comfortably inside the brief's 120–152 / 88–112 / 72–88
   ranges at every step, so #proof's own "clearly separate section" gap
   requirement (120–144 / 88–104 / 72–80) is satisfied by the same rule
   rather than a bespoke override. */
section{ padding:136px 0; }
@media(max-width:1024px){ section{ padding:96px 0; } }
@media(max-width:640px){ section{ padding:80px 0; } }
.section-head{ max-width:680px; margin-bottom:64px; }
.section-head .tag{ font-size:12.5px; letter-spacing:0.14em; text-transform:uppercase; color:var(--accent); font-weight:700; margin-bottom:16px; display:block; }
.section-head h2{ font-size:clamp(30px,4.2vw,48px); margin-bottom:18px; }
.section-head p{ color:var(--text-dim); font-size:17px; }

/* ---------- Work grid ---------- */
.work-list{ display:flex; flex-direction:column; gap:1px; background:var(--border); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; }
.work-item{ background:var(--bg); }
.work-item__head{
  display:grid; grid-template-columns:64px 1fr auto auto; align-items:center; gap:24px;
  padding:28px 30px; cursor:pointer; transition:background .2s ease, color .2s ease;
}
.work-item__head:hover{ background:var(--accent); color:#0a0b0f; }
.work-item__index{ font-size:13px; color:var(--text-faint); font-weight:700; transition:color .2s ease; }
.work-item__head:hover .work-item__index{ color:#0a0b0f; }
.work-item__title{ font-size:clamp(19px,2.4vw,26px); font-weight:700; }
.work-item__title small{ display:block; font-size:13px; font-weight:500; color:var(--text-dim); margin-top:4px; transition:color .2s ease; }
.work-item__head:hover .work-item__title small{ color:#0a0b0f; }
.work-item__meta{ font-size:12.5px; color:var(--text-faint); text-align:right; display:none; transition:color .2s ease; }
.work-item__head:hover .work-item__meta{ color:#0a0b0f; }
@media(min-width:640px){ .work-item__meta{ display:block; } }
/* Plus circle stays black even when the row goes orange on hover — it
   has no background of its own otherwise, so it would show the orange
   through it. Explicit background pins it black regardless of the row
   state (open, hover, or both). */
.work-item__plus{
  width:34px; height:34px; border-radius:50%; border:1px solid var(--border); display:flex; align-items:center; justify-content:center;
  font-size:18px; transition:transform .3s ease, background .3s ease;
}
.work-item__head:hover .work-item__plus{ background:#0a0b0f; border-color:#0a0b0f; color:var(--text); }
.work-item.open .work-item__plus{ transform:rotate(45deg); background:#0a0b0f; border-color:#0a0b0f; color:var(--text); }
.work-item__body{ max-height:0; overflow:hidden; transition:max-height .5s ease; }
.work-item.open .work-item__body{ max-height:2400px; }
/* Top padding was 0 — copy and images butted directly against the
   header/divider above with no breathing room. Matches the head's own
   28px/30px rhythm. */
.work-item__body-in{ padding:32px 30px; display:grid; grid-template-columns:1.1fr 0.9fr; gap:40px; }
@media(max-width:860px){ .work-item__body-in{ grid-template-columns:1fr; } .work-item__head{ grid-template-columns:40px 1fr auto; } }
.work-item__copy p{ color:var(--text-dim); margin-bottom:16px; font-size:15.5px; }
.work-item__copy p:last-child{ margin-bottom:0; }
.work-item__tags{ display:flex; flex-wrap:wrap; gap:8px; margin-top:20px; }
.work-item__tags span{ font-size:11.5px; padding:5px 11px; border:1px solid var(--border); border-radius:100px; color:var(--text-dim); text-transform:uppercase; letter-spacing:0.04em; }
.work-item__gallery{ display:grid; grid-template-columns:1fr; gap:10px; }
.work-item__gallery img{ border-radius:10px; border:1px solid var(--border); width:100%; height:auto; object-fit:cover; }
.work-item__gallery.two{ grid-template-columns:1fr 1fr; }
.work-item__more{ display:inline-block; margin-top:16px; color:var(--accent-2); font-weight:600; font-size:14.5px; }
.work-item__more:hover{ text-decoration:underline; }

/* ---------- Case-study image carousel ----------
   Drop-in replacement for .work-item__gallery wherever a project has more
   than a couple of source images. One slide visible at a time (crossfade),
   arrow + dot navigation, swipe on touch, arrow-key nav when focused. Degrades
   automatically to a plain single frame when there's only one slide (JS adds
   .carousel--single and strips the controls rather than showing dead arrows). */
.carousel{
  position:relative; aspect-ratio:3/2; border-radius:10px; overflow:hidden;
  border:1px solid var(--border); background:#000; outline:none;
}
/* commonSENSE-PRO's slides are mostly 16:9 app/dashboard screenshots, not the
   3:2 photography the default ratio is tuned for — at 3:2 they were getting
   cropped down both sides. Widening the frame to match fixes that without
   touching every other project's carousel. Same fix for Valcomm and the
   cinch x ITV Starstruck gallery — both are also predominantly 16:9. */
.carousel--wide{ aspect-ratio:16/9; }
/* FV.81's slides are a genuinely mixed bag — portrait phone shots, square
   crops, an ultra-wide 2.14:1 landscape — there's no single box ratio that
   fits that set without cropping most of it. Letterboxing on the existing
   black background is the only fix that doesn't cut content out of at least
   half the slides; the source images would need re-cropping to a consistent
   ratio to do better than this. */
.carousel--contain .carousel__slide img{ object-fit:contain; }
.carousel__track{ position:relative; width:100%; height:100%; }
.carousel__slide{
  position:absolute; inset:0; opacity:0; visibility:hidden; transition:opacity .5s ease;
}
.carousel__slide.is-active{ opacity:1; visibility:visible; }
.carousel__slide img{ width:100%; height:100%; object-fit:cover; display:block; }
.carousel__arrow{
  position:absolute; top:50%; transform:translateY(-50%); z-index:2;
  width:36px; height:36px; border-radius:50%; background:rgba(10,11,15,0.55); backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,0.35); color:#fff;
  display:flex; align-items:center; justify-content:center; cursor:pointer;
  opacity:0; transition:opacity .2s ease, background .2s ease, border-color .2s ease;
}
.carousel__arrow svg{ width:16px; height:16px; }
.carousel__arrow--prev{ left:10px; }
.carousel__arrow--next{ right:10px; }
.carousel:hover .carousel__arrow, .carousel:focus-visible .carousel__arrow{ opacity:1; }
.carousel__arrow:hover{ background:var(--accent); border-color:var(--accent); }
.carousel__dots{
  position:absolute; left:50%; bottom:12px; z-index:2; transform:translateX(-50%);
  display:flex; justify-content:center; gap:6px;
  padding:6px 10px; border-radius:20px; background:rgba(10,11,15,0.4); backdrop-filter:blur(6px);
}
.carousel__dot{
  width:6px; height:6px; border-radius:50%; padding:0; border:0; cursor:pointer;
  background:rgba(255,255,255,0.4); transition:background .2s ease, width .2s ease;
}
.carousel__dot.is-active{ width:18px; border-radius:3px; background:var(--accent); }
.carousel--single .carousel__arrow, .carousel--single .carousel__dots{ display:none; }
@media(hover:none){ .carousel__arrow{ opacity:1; } }

/* ---------- Landscape video row (case-study showreels/talks, 16:9) ----------
   Reuses the .reel-facade play/pause/reset system already built for the
   weServed shorts grid — .reel-facade--wide just swaps the aspect ratio from
   9:16 to 16:9, and auto-fit means a single video sits full width instead of
   stranded in a 4-column grid built for portrait clips. */
.video-row{ display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:14px; padding:0 30px 32px; }
.reel-facade.reel-facade--wide{ aspect-ratio:16/9; }
.video-row__caption{ font-size:12px; color:var(--text-faint); margin-top:8px; text-align:center; }
.video-row__cell{ display:flex; flex-direction:column; }

/* Stacks multiple reel-facade--wide videos vertically inside a single
   work-item__body-in grid column (e.g. weServed's headline reel + a
   second video), instead of the pair wrapping into a new grid row. */
.work-item__video-stack{ display:flex; flex-direction:column; gap:20px; }

/* ---------- Case-study doc strip (e.g. Brand Guidelines PDF) ---------- */
.doc-strip{
  display:flex; align-items:center; justify-content:space-between; gap:24px;
  margin:0 30px 28px; padding:20px 24px; border:1px solid var(--border); border-radius:12px;
  background:var(--surface); transition:border-color 200ms ease, background 200ms ease;
}
.doc-strip:hover{ border-color:var(--accent-2); background:var(--surface-2); }
.doc-strip__title{ display:flex; flex-direction:column; gap:6px; font-size:16px; font-weight:700; color:var(--text); }
.doc-strip__title small{ font-size:13px; font-weight:500; color:var(--text-dim); }
.doc-strip__thumb{ position:relative; flex:0 0 auto; width:140px; aspect-ratio:16/9; border-radius:8px; overflow:hidden; border:1px solid var(--border); }
.doc-strip__thumb img{ width:100%; height:100%; object-fit:cover; display:block; }
.doc-strip__cta{
  position:absolute; inset:auto 0 0 0; padding:6px 0; font-size:11px; font-weight:700;
  letter-spacing:0.02em; text-align:center; color:#fff; background:rgba(10,11,15,0.75);
}
@media(max-width:640px){
  .doc-strip{ flex-direction:column; align-items:flex-start; margin:0 20px 24px; }
  .doc-strip__thumb{ width:100%; }
}

/* ---------- PDLC process strip ---------- */
/* One self-contained card: everything (steps, archiving/access chips, team
   loop) reads as a single unit, clearly bounded off from the reels below —
   no internal divider lines that could read as a section break. */
.pdlc{ margin:0 30px 32px; padding:28px 26px 30px; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); }
.pdlc__head{ max-width:640px; margin-bottom:28px; }
.pdlc__tag{ font-size:12.5px; letter-spacing:0.14em; text-transform:uppercase; color:var(--accent-2); font-weight:700; margin-bottom:10px; display:block; }
.pdlc__head h4{ font-size:19px; margin-bottom:8px; }
.pdlc__head p{ font-size:14px; color:var(--text-dim); line-height:1.55; }

.pdlc__steps{ position:relative; display:flex; gap:0; margin-bottom:32px; }
.pdlc__steps::before{ content:''; position:absolute; top:15px; left:4%; right:4%; height:1px; background:var(--border); z-index:0; }
.pdlc__step{ flex:1 1 0; min-width:0; position:relative; z-index:1; display:flex; flex-direction:column; align-items:center; text-align:center; padding:0 4px; }
.pdlc__num{
  width:30px; height:30px; border-radius:50%; background:var(--surface); border:1px solid var(--border);
  display:flex; align-items:center; justify-content:center; font-size:12px; font-weight:800; color:var(--accent-2);
  margin-bottom:10px; flex-shrink:0;
}
.pdlc__step--archive .pdlc__num{ color:var(--accent); border-color:var(--accent); }
.pdlc__label{ font-size:12px; font-weight:700; color:var(--text); line-height:1.3; }
.pdlc__sub{ font-size:10.5px; color:var(--text-faint); margin-top:5px; line-height:1.4; }

.pdlc__gov{ display:grid; grid-template-columns:1fr 1fr; gap:24px; margin-bottom:24px; }
.pdlc__gov-label{ font-size:11.5px; letter-spacing:0.08em; text-transform:uppercase; color:var(--text-faint); font-weight:700; margin-bottom:10px; display:block; }
.pdlc__chips{ display:flex; flex-wrap:wrap; gap:8px; }
.pdlc__chips span{ font-size:12px; padding:7px 13px; background:var(--surface); border:1px solid var(--border); border-radius:6px; color:var(--text-dim); }
.pdlc__team{ margin-top:22px; }
.pdlc__chips--flow .is-lead{ border-color:var(--accent-2); color:var(--text); }

@media(max-width:760px){
  .pdlc__steps{ flex-wrap:wrap; row-gap:20px; }
  .pdlc__steps::before{ display:none; }
  .pdlc__step{ flex:1 1 22%; min-width:70px; }
  .pdlc__gov{ grid-template-columns:1fr; }
}

.work-item__reels{ display:grid; grid-template-columns:repeat(4,1fr); gap:14px; padding:0 30px 32px; }
.work-item__reels iframe{ width:100%; aspect-ratio:9/16; border:1px solid var(--border); border-radius:12px; background:#000; }
@media(max-width:900px){ .work-item__reels{ grid-template-columns:repeat(2,1fr); } }
@media(max-width:520px){ .work-item__reels{ grid-template-columns:1fr; padding:0 20px 32px; } }

.reel-facade{
  position:relative; width:100%; aspect-ratio:9/16; border:1px solid var(--border); border-radius:12px;
  overflow:hidden; padding:0; background:#000; cursor:pointer;
}
.reel-facade img{ width:100%; height:100%; object-fit:cover; display:block; transition:transform .4s ease; }
.reel-facade:hover img{ transform:scale(1.04); }
.reel-facade::after{ content:''; position:absolute; inset:0; background:linear-gradient(180deg, rgba(0,0,0,0.05) 55%, rgba(0,0,0,0.55) 100%); }
.reel-facade__play{
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); z-index:1;
  width:52px; height:52px; border-radius:50%; background:rgba(10,11,15,0.55); backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,0.35); color:var(--accent-2);
  display:flex; align-items:center; justify-content:center; transition:transform .2s ease, background .2s ease, color .2s ease;
}
.reel-facade__play svg{ width:20px; height:20px; display:block; }
.reel-facade:hover .reel-facade__play{ transform:translate(-50%,-50%) scale(1.1); background:var(--accent); border-color:var(--accent); color:#fff; }
.reel-facade iframe, .reel-facade video{ position:absolute; inset:0; width:100%; height:100%; border:0; object-fit:cover; background:#000; }
.reel-facade video{ cursor:pointer; }

/* ---------- AI Ops section ---------- */
.aiops{ background:var(--bg-alt); border-top:1px solid var(--border); border-bottom:1px solid var(--border); }
.aiops__intro{ display:grid; grid-template-columns:0.42fr 0.58fr; gap:16px; align-items:start; margin-bottom:48px; padding:36px; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); }
@media(max-width:860px){ .aiops__intro{ grid-template-columns:1fr; gap:24px; } }
.aiops__intro-support{ padding-top:4px; }
.aiops__intro-support p{ color:var(--text-dim); font-size:14.5px; max-width:52ch; text-wrap:pretty; }
.aiops__intro-support p + p{ margin-top:16px; }
@media(min-width:861px){ .aiops__intro-support{ border-left:1px solid var(--border); padding-left:32px; } }
.sr-only{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }

/* Kinetic "Human:" tag — static label, one word from the cycle showing at a
   time. Sits where the old "Video coming soon" tag was, above the aiops
   intro headline. Words are stacked absolutely inside a fixed-width wrapper
   so the cycle doesn't shove the label sideways as word length changes. */
.kinetic-tag{ display:flex; align-items:baseline; gap:8px; margin-bottom:12px; font-size:12.5px; letter-spacing:0.14em; text-transform:uppercase; font-weight:700; }
.kinetic-tag__label{ color:var(--accent); }
.kinetic-tag__word-wrap{ position:relative; display:inline-block; min-width:9ch; height:1em; color:var(--text-dim); }
.kinetic-tag__word{
  position:absolute; left:0; top:0; white-space:nowrap;
  opacity:0; transform:translateY(6px);
  animation:kineticWord 8s ease-in-out infinite;
}
.kinetic-tag__word:nth-child(1){ animation-delay:0s; }
.kinetic-tag__word:nth-child(2){ animation-delay:-6s; }
.kinetic-tag__word:nth-child(3){ animation-delay:-4s; }
.kinetic-tag__word:nth-child(4){ animation-delay:-2s; }
@keyframes kineticWord{
  0%   { opacity:0; transform:translateY(6px); }
  6%   { opacity:1; transform:translateY(0); }
  20%  { opacity:1; transform:translateY(0); }
  25%  { opacity:0; transform:translateY(-6px); }
  100% { opacity:0; transform:translateY(-6px); }
}

.aiops__intro-lead h3{ font-size:clamp(19px,2.4vw,24px); margin-bottom:12px; line-height:1.3; text-wrap:balance; }
.aiops__intro-lead p{ color:var(--text-dim); font-size:14.5px; text-wrap:pretty; }
.aiops__intro-media{ max-width:340px; margin:0 auto; text-align:center; }
.aiops__intro-video{ position:relative; aspect-ratio:1/1; border-radius:50%; overflow:hidden; background:transparent; }
.aiops__intro-video img{ width:100%; height:100%; object-fit:cover; display:block; }
.aiops__intro-badge{
  display:inline-flex; align-items:center; gap:6px; margin-top:14px; font-size:11.5px; font-weight:700; letter-spacing:0.06em;
  text-transform:uppercase; color:#fff; background:rgba(10,11,15,0.6); backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,0.3); padding:6px 12px; border-radius:100px; white-space:nowrap;
}
.aiops__intro-play{
  position:absolute; top:68%; left:50%; transform:translate(-50%,-50%) scale(1); z-index:2;
  width:48px; height:48px; border-radius:50%; background:rgba(10,11,15,0.55); backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,0.35); color:#fff; cursor:pointer; padding:0;
  display:flex; align-items:center; justify-content:center; transition:transform .2s ease, background .2s ease, border-color .2s ease;
}
.aiops__intro-play svg{ width:19px; height:19px; display:block; }
.aiops__intro-video:hover .aiops__intro-play{ background:var(--accent); border-color:var(--accent); }
.aiops__intro-play.is-playing{ transform:translate(-50%,-50%) scale(0.92); }
.aiops__grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:1px; background:var(--border); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; margin-bottom:56px; }
@media(max-width:860px){ .aiops__grid{ grid-template-columns:repeat(2,1fr);} }
@media(max-width:560px){ .aiops__grid{ grid-template-columns:1fr;} }
.aiops__card{ background:var(--bg); padding:28px 26px; }
.aiops__card .role{ font-size:12px; letter-spacing:0.1em; text-transform:uppercase; color:var(--accent-2); font-weight:700; margin-bottom:10px; }
.aiops__card h4{ font-size:18px; margin-bottom:10px; }
.aiops__card p{ font-size:14px; color:var(--text-dim); }
.aiops__quote{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:40px;
  font-size:clamp(18px,2.4vw,24px); line-height:1.5; color:var(--text); font-weight:500;
}
.aiops__quote span{ color:var(--text-faint); font-size:13px; display:block; margin-top:20px; font-weight:600; }
.stack-row{ display:flex; flex-wrap:wrap; gap:10px; margin-top:16px; }
.stack-row span{ font-size:13px; padding:8px 14px; background:var(--surface); border:1px solid var(--border); border-radius:8px; color:var(--text-dim); }

/* ---------- Selected production stack ---------- */
.stack-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:16px; }
@media(max-width:640px){ .stack-grid{ grid-template-columns:1fr; } }
.stack-panel{
  position:relative; background:var(--surface); padding:28px 26px; overflow:hidden;
  transition:transform 200ms cubic-bezier(0.23,1,0.32,1);
}
@media (hover:hover) and (pointer:fine){
  .stack-panel:hover{ transform:translateY(-3px); }
}
.stack-panel__num{
  position:absolute; top:4px; right:16px; z-index:0; font-size:clamp(48px,5vw,72px); font-weight:800;
  color:var(--text); opacity:0.06; line-height:1; pointer-events:none;
}
.stack-panel h4{ position:relative; z-index:1; font-size:17px; margin-bottom:14px; }
.stack-panel__rule{ position:relative; z-index:1; display:block; width:28px; height:2px; background:var(--accent-2); margin-bottom:16px; }
.stack-panel__chips{ position:relative; z-index:1; list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; gap:8px; }
.stack-panel__chips li{
  font-size:12.5px; color:var(--text-dim); border:1px solid var(--border); border-radius:100px; padding:5px 12px;
}
.flip-card{ appearance:none; display:block; width:100%; height:178px; padding:0; border:0; border-radius:var(--radius); background:none; color:var(--text); text-align:left; perspective:1400px; cursor:pointer; transition:transform .28s ease, filter .28s ease; }
.flip-card__inner{ position:relative; display:block; width:100%; height:100%; transition:transform .82s cubic-bezier(.22,.75,.18,1); transform-style:preserve-3d; }
.flip-card.is-flipped .flip-card__inner{ transform:rotateY(180deg); }
.flip-card__face{ position:absolute; inset:0; display:flex; flex-direction:column; justify-content:center; padding:28px; border:1px solid var(--border); border-radius:var(--radius); backface-visibility:hidden; -webkit-backface-visibility:hidden; box-shadow:0 16px 38px rgba(0,0,0,.12); }
.flip-card__front{ background:linear-gradient(145deg,rgba(29,33,43,.96),rgba(17,19,25,.98)); }
.flip-card__back{ gap:7px; background:linear-gradient(145deg,var(--surface-2),var(--surface)); color:var(--text-dim); font-size:13px; transform:rotateY(180deg); }
.flip-card__tag{ color:var(--accent-2); font-size:11px; font-weight:800; letter-spacing:.12em; margin-bottom:9px; }
.flip-card__front strong{ font-size:17px; }
.flip-card__hint{ margin-top:18px; color:var(--text-faint); font-size:11.5px; transition:color .25s ease; }
.flip-card:focus-visible{ outline:2px solid var(--accent-2); outline-offset:4px; border-radius:var(--radius); }
@media(hover:hover) and (pointer:fine){
  .flip-card:hover{ transform:translateY(-3px); filter:brightness(1.05); }
  .flip-card:hover .flip-card__hint{ color:var(--accent-2); }
}

/* ---------- Approach ---------- */
.approach__grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:32px; }
@media(max-width:860px){ .approach__grid{ grid-template-columns:1fr; } }
.approach__item .n{ font-size:13px; color:var(--accent); font-weight:800; margin-bottom:14px; }
.approach__item h3{ font-size:20px; margin-bottom:12px; }
.approach__item p{ font-size:15px; color:var(--text-dim); }

/* ---------- Global delivery route ---------- */
.global{ border-top:1px solid var(--border); border-bottom:1px solid var(--border); background:var(--bg-alt); }
.route{ position:relative; display:flex; justify-content:space-between; gap:28px; flex-wrap:wrap; padding-top:8px; }
.route::before{
  content:''; position:absolute; top:6px; left:0; right:0; height:1px;
  background:linear-gradient(90deg, var(--border) 0%, var(--border) 100%); z-index:0;
}
.route__node{ position:relative; z-index:1; display:flex; flex-direction:column; align-items:flex-start; gap:8px; flex:1 1 140px; min-width:140px; }
.route__dot{
  width:13px; height:13px; border-radius:50%; background:var(--bg-alt); border:2px solid var(--accent-2);
  animation:pulseDot 2.8s ease-out infinite;
}
.route__node--home .route__dot, .route__node--more .route__dot{ border-color:var(--accent); animation-name:pulseDotAccent; }
.route__node:nth-child(2) .route__dot{ animation-delay:.3s; }
.route__node:nth-child(3) .route__dot{ animation-delay:.6s; }
.route__node:nth-child(4) .route__dot{ animation-delay:.9s; }
.route__node:nth-child(5) .route__dot{ animation-delay:1.2s; }
.route__node:nth-child(6) .route__dot{ animation-delay:1.5s; }
.route__city{ font-size:14px; font-weight:700; color:var(--text); }
.route__note{ font-size:12.5px; color:var(--text-faint); }
@keyframes pulseDot{
  0%{ box-shadow:0 0 0 0 rgba(73,224,184,0.45); }
  70%{ box-shadow:0 0 0 10px rgba(73,224,184,0); }
  100%{ box-shadow:0 0 0 0 rgba(73,224,184,0); }
}
@keyframes pulseDotAccent{
  0%{ box-shadow:0 0 0 0 rgba(255,90,60,0.45); }
  70%{ box-shadow:0 0 0 10px rgba(255,90,60,0); }
  100%{ box-shadow:0 0 0 0 rgba(255,90,60,0); }
}
@media(max-width:760px){
  .route{ flex-direction:column; gap:22px; }
  .route::before{ top:0; bottom:0; left:6px; right:auto; width:1px; height:auto; background:var(--border); }
  .route__node{ flex-direction:row; align-items:center; padding-left:26px; min-width:0; }
  .route__node .route__dot{ position:absolute; left:0; }
  .route__node > span:not(.route__dot){ margin-left:0; }
  .route__city{ margin-right:8px; }
}

/* ---------- Testimonials ---------- */
.testi{ background:var(--bg-alt); border-top:1px solid var(--border); border-bottom:1px solid var(--border); }
.testi__grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:1px; background:var(--border); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; }
@media(max-width:900px){ .testi__grid{ grid-template-columns:repeat(2,1fr);} }
@media(max-width:600px){ .testi__grid{ grid-template-columns:1fr;} }
.testi__card{ background:var(--bg); padding:30px; display:flex; flex-direction:column; gap:18px; }
.testi__card p{ font-size:14.5px; color:var(--text-dim); flex:1; }
.testi__card .who{ font-size:13px; font-weight:700; color:var(--text); }
.testi__card .role{ font-size:12px; color:var(--text-faint); }
.testi__person{ display:flex; align-items:center; gap:10px; }
.testi__avatar{ width:30px; height:30px; border-radius:50%; object-fit:cover; flex-shrink:0; border:1px solid var(--border); background:#fff; }
.testi__prompt{ display:none; order:99; min-height:100%; padding:30px; border:0; background:var(--bg); color:var(--text); text-align:left; cursor:pointer; }
.testi__prompt-count{ display:block; margin-bottom:auto; color:var(--accent-2); font-size:clamp(42px,6vw,68px); font-weight:800; line-height:1; letter-spacing:-.05em; opacity:.75; }
.testi__prompt strong{ display:block; margin:28px 0 8px; font-size:18px; }
.testi__prompt-action{ color:var(--text-dim); font-size:13px; }
.testi__prompt:hover .testi__prompt-action{ color:var(--accent-2); }
.testi__prompt:focus-visible{ position:relative; z-index:1; outline:2px solid var(--accent-2); outline-offset:-4px; }
@media(min-width:601px) and (max-width:900px){
  .testi__prompt{ display:flex; flex-direction:column; }
  .testi__more-toggle{ display:none !important; }
}

/* ---------- About ---------- */
.about__grid{ display:grid; grid-template-columns:0.85fr 1.15fr; gap:64px; align-items:start; }
@media(max-width:900px){ .about__grid{ grid-template-columns:1fr; } }
.about__mark{
  aspect-ratio:1; border-radius:var(--radius); background:linear-gradient(155deg, var(--navy), #0f1526);
  border:1px solid var(--border); display:flex; align-items:center; justify-content:center; position:relative; overflow:hidden;
}
.about__mark::after{ content:'TH'; font-size:120px; font-weight:800; color:rgba(255,255,255,0.06); letter-spacing:-0.05em; }
.about__mark.reel-facade::after{ content:none; }
.about p{ color:var(--text-dim); font-size:16.5px; margin-bottom:18px; }
.about p:last-child{ margin-bottom:0; }
.about strong{ color:var(--text); }
.about__skills{ margin-top:28px; display:flex; flex-wrap:wrap; gap:8px; }
.about__skills span{ font-size:12.5px; padding:6px 12px; border:1px solid var(--border); border-radius:100px; color:var(--text-dim); }

/* ---------- Aside / personal (NSX) ---------- */
/* Full-width text on top at a comfortable editorial measure (not
   stretched across the whole container), then one two-column media row
   below — carousel and video share the same 16:9 aspect ratio (see the
   .carousel--wide class added to the carousel in the markup) so their
   top and bottom edges align exactly, replacing the old 3-item grid
   that stranded the video under column 1 with dead space beside it. */
.aside{ display:flex; flex-direction:column; gap:40px; }
.aside__text{ max-width:62ch; }
.aside h2{ font-size:clamp(26px,3.4vw,38px); margin-bottom:18px; text-wrap:balance; }
.aside p{ color:var(--text-dim); font-size:16px; margin-bottom:14px; text-wrap:pretty; }
.aside__media{ display:grid; grid-template-columns:1fr 1fr; gap:24px; align-items:start; }
@media(max-width:860px){ .aside__media{ grid-template-columns:1fr; } }
.aside__media .video-row{ padding:0; display:block; }
/* display:block on the button removes the inline-block descender gap
   that was leaving the video ~7px taller than the carousel despite
   matching aspect ratios and widths. */
.aside__media .video-row .reel-facade{ display:block; border-radius:10px; height:100%; }

/* ---------- Contact ---------- */
.contact{ text-align:center; }
.contact h2{ font-size:clamp(34px,6vw,64px); margin-bottom:24px; }
.contact p{ color:var(--text-dim); font-size:17px; max-width:520px; margin:0 auto 40px; }
.contact__actions{ display:flex; gap:16px; justify-content:center; flex-wrap:wrap; margin-bottom:56px; }
.contact__details{ display:flex; gap:36px; justify-content:center; flex-wrap:wrap; font-size:14px; color:var(--text-dim); }
.contact__details a:hover{ color:var(--text); }

/* ---------- Showreel modal ---------- */
.reel-modal{ position:fixed; inset:0; z-index:1000; display:none; align-items:center; justify-content:center; padding:40px; }
.reel-modal.open{ display:flex; }
.reel-modal__backdrop{ position:absolute; inset:0; background:rgba(6,7,10,0.9); backdrop-filter:blur(6px); }
.reel-modal__inner{ position:relative; width:100%; max-width:960px; z-index:1; }
.reel-modal__inner video{ width:100%; border-radius:12px; display:block; background:#000; box-shadow:0 30px 80px rgba(0,0,0,0.6); }
.reel-modal__close{
  position:absolute; top:-46px; right:0; width:36px; height:36px; border-radius:50%;
  background:var(--surface); border:1px solid var(--border); color:var(--text); font-size:16px;
}
.reel-modal__close:hover{ background:var(--surface-2); }

/* ---------- CV request modal ---------- */
.cv-request-trigger{ font:inherit; cursor:pointer; }
.cv-modal{ position:fixed; inset:0; z-index:1000; display:none; align-items:center; justify-content:center; padding:40px; }
.cv-modal.open{ display:flex; }
.cv-modal__backdrop{ position:absolute; inset:0; background:rgba(6,7,10,0.9); backdrop-filter:blur(6px); }
.cv-modal__inner{
  position:relative; width:100%; max-width:420px; z-index:1; background:var(--surface); border:1px solid var(--border);
  border-radius:16px; padding:40px; text-align:center; box-shadow:0 30px 80px rgba(0,0,0,0.6);
}
.cv-modal__inner h3{ font-size:22px; margin-bottom:12px; }
.cv-modal__inner p{ color:var(--text-dim); font-size:15px; margin-bottom:24px; }
.cv-modal__inner p a{ color:var(--text); }
.cv-modal__close{
  position:absolute; top:-46px; right:0; width:36px; height:36px; border-radius:50%;
  background:var(--surface); border:1px solid var(--border); color:var(--text); font-size:16px;
}
.cv-modal__close:hover{ background:var(--surface-2); }

/* ---------- Design enquiry modal ---------- */
.enquiry-modal{ position:fixed; inset:0; z-index:1150; display:none; align-items:center; justify-content:center; padding:28px; }
.enquiry-modal.open{ display:flex; }
.enquiry-modal__backdrop{ position:absolute; inset:0; background:rgba(6,7,10,.92); backdrop-filter:blur(8px); }
.enquiry-modal__inner{ position:relative; z-index:1; width:min(640px,100%); max-height:calc(100vh - 56px); overflow:auto; padding:38px; border:1px solid var(--border); border-radius:18px; background:var(--surface); box-shadow:0 30px 90px rgba(0,0,0,.65); }
.enquiry-modal__inner::before{ content:''; position:absolute; left:0; top:28px; bottom:28px; width:2px; background:linear-gradient(180deg,var(--accent-2),rgba(229,255,83,.14)); }
.enquiry-modal__inner h3{ margin:12px 0 10px; font-size:clamp(24px,4vw,34px); line-height:1.15; }
.enquiry-modal__intro{ margin-bottom:24px; color:var(--text-dim); font-size:14px; }
.enquiry-modal__close{ position:absolute; top:16px; right:16px; width:38px; height:38px; border-radius:50%; border:1px solid var(--border); background:var(--surface-2); color:var(--text); }
.enquiry-modal form,.enquiry-modal label{ display:flex; flex-direction:column; gap:8px; }
.enquiry-modal form{ gap:16px; }
.enquiry-form__row{ display:grid; grid-template-columns:1fr 1fr; gap:14px; }
.enquiry-modal label{ color:var(--text-dim); font-size:13px; font-weight:650; }
.enquiry-modal input,.enquiry-modal select,.enquiry-modal textarea{ width:100%; padding:12px 14px; border:1px solid var(--border); border-radius:9px; background:var(--bg); color:var(--text); font:inherit; font-size:15px; }
.enquiry-modal textarea{ resize:vertical; }
.enquiry-modal input:focus-visible,.enquiry-modal select:focus-visible,.enquiry-modal textarea:focus-visible{ outline:2px solid var(--accent-2); outline-offset:1px; }
.enquiry-form__actions{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-top:4px; }
.enquiry-form__actions span{ color:var(--text-faint); font-size:11.5px; }
@media(max-width:560px){ .enquiry-modal{ padding:14px; }.enquiry-modal__inner{ padding:30px 22px; }.enquiry-form__row{ grid-template-columns:1fr; } }

/* ---------- Reel lightbox (project-card reels: weServed shorts, JAD
   SmartMerc, NSX rebuild, etc.) ----------
   These play full-viewport via this shared overlay rather than the browser's
   native Fullscreen API. iOS Safari only supports that API on a bare
   <video>, not on iframes, without an experimental flag almost no visitor
   has switched on — so an embedded Vimeo/YouTube reel would silently stay
   stuck at in-card size there. This layer is entirely ours to control, so
   every reel, self-hosted or embedded, gets the same true full-screen,
   letterboxed treatment on every device. object-fit:contain on the player
   itself is what keeps a portrait reel's full frame on screen — top to
   bottom — with black bars taking up the left/right rather than cropping it,
   and the same for a landscape reel on a narrow phone screen. */
.reel-lightbox{ position:fixed; inset:0; z-index:1100; display:none; align-items:center; justify-content:center; }
.reel-lightbox.open{ display:flex; }
.reel-lightbox__backdrop{ position:absolute; inset:0; background:#000; }
.reel-lightbox__stage{ position:relative; width:100%; height:100%; display:flex; align-items:center; justify-content:center; }
.reel-lightbox__stage video, .reel-lightbox__stage iframe{ width:100%; height:100%; border:0; object-fit:contain; background:#000; }
.reel-lightbox__close{
  position:absolute; top:16px; right:16px; z-index:2; width:40px; height:40px; border-radius:50%;
  background:rgba(23,26,34,0.85); border:1px solid var(--border); color:var(--text); font-size:16px;
}
.reel-lightbox__close:hover{ background:var(--surface-2); }

footer{ border-top:1px solid var(--border); padding:32px 0; }
.footer__row{ display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:12px; font-size:13px; color:var(--text-faint); }
.footer__row a{ color:var(--text-faint); }
.footer__row a:hover{ color:var(--text-dim); }
.footer__links{ display:flex; align-items:center; justify-content:flex-end; flex-wrap:wrap; gap:18px; }
.footer__link{ padding:0; border:0; background:none; color:var(--text-faint); font:inherit; }
.footer__link:hover{ color:var(--text-dim); }
.footer__row a:focus-visible,.footer__link:focus-visible{ outline:2px solid var(--accent-2); outline-offset:3px; border-radius:2px; }

/* ---------- Individual project pages ----------
   Shared across every dedicated case-study page under /work/<slug>/.
   Homepage accordion entries are untouched by any of this — these are new,
   additive classes for a project's own standalone page: title/meta header,
   a large contained lead image, longer-form copy set slightly larger and
   lighter than the homepage accordion for sustained reading, the existing
   .carousel component reused as-is for the gallery, and a plain link back
   to the full work list (a genuine related-projects grid can follow once
   more than one project has its own page to link to). */
.proj-head{ margin-bottom:40px; }
.proj-head__eyebrow{ font-size:12.5px; letter-spacing:0.14em; text-transform:uppercase; color:var(--accent); font-weight:700; margin-bottom:16px; display:block; }
.proj-head h1{ font-size:clamp(32px,4.5vw,52px); margin-bottom:8px; }
.proj-head__prop{ font-size:17px; color:var(--text-dim); margin-bottom:24px; font-weight:400; max-width:640px; }
.proj-head__facts{ display:flex; flex-wrap:wrap; gap:16px 40px; padding:22px 0; margin-bottom:24px; border-top:1px solid var(--border); border-bottom:1px solid var(--border); }
.proj-head__fact{ font-size:14.5px; color:var(--text-dim); }
.proj-head__fact strong{ display:block; font-size:11px; color:var(--text-faint); text-transform:uppercase; letter-spacing:0.06em; font-weight:700; margin-bottom:5px; }
.proj-head__tags{ display:flex; flex-wrap:wrap; gap:8px; }

.proj-hero{ border-radius:var(--radius); overflow:hidden; border:1px solid var(--border); margin-bottom:40px; aspect-ratio:16/10; background:#000; }
.proj-hero img{ width:100%; height:100%; object-fit:contain; }
/* Matches weserved-employment-campaign-cover.jpg's exact source ratio
   (1900x1266) so the artwork fills the box with no side pillarbox —
   scoped here rather than changing the shared 16:10 .proj-hero default. */
.proj-hero--employment{ aspect-ratio:1900/1266; }
/* Only present when a hero image's provenance needs an explicit, visible
   credit line (e.g. reproduced project material of unconfirmed origin) —
   pulls the hero's own margin-bottom up to sit directly under the image. */
.proj-hero + .proj-hero__caption{ margin-top:-28px; margin-bottom:40px; font-size:14px; color:var(--text-body); border-left:2px solid var(--accent-2); padding-left:12px; }

.proj-main{ max-width:65ch; margin-bottom:48px; }
.proj-main h2{ font-size:19px; margin:32px 0 14px; }
.proj-main h2:first-child{ margin-top:0; }
.proj-main h3{ font-size:12px; margin:20px 0 10px; color:var(--text-faint); text-transform:uppercase; letter-spacing:0.06em; font-weight:700; }
.proj-main p{ color:var(--text-body); font-size:17.5px; line-height:1.7; margin-bottom:20px; }
.proj-main ul{ margin:0 0 20px; padding-left:0; }
.proj-main li{ position:relative; padding-left:22px; color:var(--text-body); font-size:17.5px; line-height:1.7; margin-bottom:10px; }
.proj-main li::before{ content:''; position:absolute; left:2px; top:11px; width:6px; height:6px; border-radius:50%; background:var(--accent-2); }
.proj-main li:last-child{ margin-bottom:0; }
.proj-status{ border-top:1px solid var(--border); padding-top:16px; margin-top:8px; font-size:15px; color:var(--text-body); max-width:65ch; }
.proj-status strong{ color:var(--text-faint); display:inline; margin-right:8px; font-size:11px; text-transform:uppercase; letter-spacing:0.06em; font-weight:700; }

.proj-gallery{ margin-bottom:48px; }
.proj-gallery .carousel{ margin-bottom:14px; }
.proj-gallery__caption{ font-size:14px; color:var(--text-body); border-left:2px solid var(--accent-2); padding-left:12px; min-height:20px; }

.proj-back{ border-top:1px solid var(--border); padding-top:32px; font-size:14px; color:var(--text-dim); }
.proj-back a{ color:var(--accent-2); font-weight:600; }
.proj-back a:hover{ text-decoration:underline; }

/* .video-row's own 30px side padding is tuned for sitting inside a
   work-item accordion body, not directly inside .container (which already
   provides the page gutter) — flush variant for use on a project page. */
.video-row--flush{ padding-left:0; padding-right:0; margin-bottom:8px; }

/* Same fix for the other work-item-scoped components a video-led page like
   weServed's reuses directly inside .container: .doc-strip and .pdlc carry
   their own 30px side margin, .work-item__reels its own 30px side padding —
   all tuned for a zero-padding .work-item ancestor, not .container. */
.doc-strip--flush{ margin-left:0; margin-right:0; }
.pdlc--flush{ margin-left:0; margin-right:0; }
.work-item__reels--flush{ padding-left:0; padding-right:0; }

/* Every project page's opening section sits directly under the fixed nav
   with no hero above it to push it clear — shared id, reused per page. */
#case-study{ padding-top:160px; }

/* ==========================================================================
   ISOLATED PROTOTYPE — homepage Work section only. Everything above this
   point is untouched production CSS (hero, nav, footer, other sections,
   the base accordion). Colour logic stays production's: orange hover with
   dark ink text is untouched below; chartreuse (--accent-2, already the
   approved production token) is used only for the arrow glyph and the one
   highlighted word in the section heading — nothing here re-themes the
   accordion's default or hover states.
   ========================================================================== */

/* Short-proposition display type — reduced from V2's clamp(32-64px) and
   given tight leading (1.08 vs. body copy's inherited 1.6) so it reads as
   one composed line, not stacked/separated words. Used once, on the
   section's own six-word heading — not on paragraphs or item titles other
   than the flagship's (below). */
.section-head h2.work-section__display{
  font-size:clamp(26px, 3.4vw, 40px);
  line-height:1.08;
  font-weight:800;
  letter-spacing:-0.02em;
  margin-bottom:18px;
}
.work-section__display b{ color:var(--accent-2); font-weight:800; }

/* weServed — a completely standard accordion item (same plus/close
   control, same click + keyboard behaviour, same single-open-at-a-time
   JS as every other row; opens by default on first load only because
   script.js's existing "open first item on desktop" logic still applies
   to it, being item 1 — nothing here overrides that state). The
   work-item--flagship class is a pure typography hook: its title reads
   larger than a compact row's, per the approved typography experiment.
   Its body content is long-form (the full case-study material), so this
   item alone gets a single-column body layout instead of the standard
   copy+gallery two-column split — every other row keeps the original grid. */
.work-item--flagship .work-item__title{
  font-size:clamp(28px, 3.6vw, 40px);
  line-height:1.12;
}
.work-item--flagship .work-item__body-in{ grid-template-columns:1fr; gap:0; }
/* Bug fix: .proj-main's own max-width:65ch (~520-580px) left it flush-left
   inside the much wider single-column body, leaving a large empty area on
   the right. Widened and centred within the available body width — the
   artwork, video stack, doc-strip, reels and process graphics below are
   deliberately left unconstrained here so they keep their intended wider
   layouts. */
.work-item--flagship .proj-main{ max-width:860px; margin-left:auto; margin-right:auto; }

/* "Learn more ↘" — replaces the old text-arrow link. Chunky geometric SVG
   (stroke-drawn diagonal + right-angle head) instead of a system-font
   glyph, so its weight and alignment are controlled. Arrow sits low and to
   the right of the label via align-items:flex-end; link and arrow share
   one hover/focus response so they read as a single control. */
.work-item__more{
  display:inline-flex; align-items:flex-end; gap:8px;
  margin-top:16px; color:var(--text); font-weight:700; font-size:14.5px;
}
.work-item__more-label{ transition:opacity .2s ease; }
.work-item__more-arrow{
  color:var(--accent-2); flex-shrink:0; transform:translateY(0);
  transition:transform .2s ease;
}
.work-item__more:hover, .work-item__more:focus-visible{ color:var(--accent-2); text-decoration:none; }
.work-item__more:hover .work-item__more-arrow,
.work-item__more:focus-visible .work-item__more-arrow{ transform:translate(3px, 3px); }
.work-item__more:focus-visible{ outline:2px solid var(--accent-2); outline-offset:4px; border-radius:2px; }


/* ==========================================================================
   CLIENT AREA — Stage 1 (front-end preview only; no backend, no live auth).
   Shared green CTA used both in the pre-footer invite and the auth card's
   Sign In action, so the two moments read as one coherent gesture.
   ========================================================================== */
.btn--client{ background:var(--accent-2); color:var(--bg); }
.btn--client:hover{ background:#eeff7a; transform:translateY(-2px); box-shadow:0 0 20px rgba(229,255,83,0.28); }
.btn--client:focus-visible{ outline:2px solid var(--accent-2); outline-offset:3px; }
.btn--client:disabled{ background:var(--surface-2); color:var(--text-faint); cursor:not-allowed; transform:none !important; box-shadow:none !important; }
.btn--client:disabled:hover{ background:var(--surface-2); }

/* ---------- Pre-footer Client Area invitation ---------- */
/* Deliberately modest: a bordered band, not another full-viewport hero. */
.client-invite{
  position:relative; overflow:hidden;
  background:var(--bg-alt); border-top:1px solid var(--border); border-bottom:1px solid var(--border);
  padding:72px 0;
}
.client-invite::before{
  content:''; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(ellipse 560px 280px at 50% 0%, rgba(229,255,83,0.07), transparent 70%);
}
.client-invite__inner{ position:relative; z-index:1; max-width:560px; margin:0 auto; text-align:center; }
.client-invite__eyebrow{
  display:inline-flex; align-items:center; gap:8px; font-size:12px; font-weight:700; letter-spacing:0.16em;
  text-transform:uppercase; color:var(--accent-2); margin-bottom:16px;
}
.client-invite__eyebrow::before{ content:''; width:6px; height:6px; border-radius:50%; background:var(--accent-2); box-shadow:0 0 10px var(--accent-2); }
.client-invite__line{ font-size:clamp(22px,2.6vw,30px); font-weight:800; letter-spacing:-0.015em; margin-bottom:12px; }
.client-invite__sub{ font-size:15px; color:var(--text-dim); line-height:1.55; margin-bottom:28px; }

/* ---------- Newsletter — "Studio Notes" ---------- */
/* Same banded treatment as .client-invite (bg-alt, bordered, radial glow),
   but laid out as copy alongside a working form rather than a single CTA,
   so it earns the extra width on wide viewports. */
.newsletter{
  position:relative; overflow:hidden;
  background:var(--bg-alt); border-top:1px solid var(--border); border-bottom:1px solid var(--border);
  padding:64px 0;
}
.newsletter::before{
  content:''; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(ellipse 560px 280px at 100% 0%, rgba(229,255,83,0.06), transparent 70%);
}
.newsletter__inner{
  position:relative; z-index:1; max-width:var(--maxw); margin:0 auto; padding:0 32px;
  display:grid; grid-template-columns:1fr 1fr; gap:48px; align-items:center;
}
.newsletter__eyebrow{
  display:inline-flex; align-items:center; gap:8px; font-size:12px; font-weight:700; letter-spacing:0.16em;
  text-transform:uppercase; color:var(--accent-2); margin-bottom:14px;
}
.newsletter__eyebrow::before{ content:''; width:6px; height:6px; border-radius:50%; background:var(--accent-2); box-shadow:0 0 10px var(--accent-2); }
.newsletter__heading{ font-size:clamp(24px,2.8vw,32px); font-weight:800; letter-spacing:-0.015em; margin-bottom:10px; }
.newsletter__sub{ font-size:15px; color:var(--text-dim); line-height:1.55; max-width:44ch; }

.newsletter__field{ display:flex; gap:10px; }
.newsletter__field input{
  flex:1; min-width:0; padding:13px 16px; border-radius:10px; border:1px solid var(--border);
  background:var(--bg); color:var(--text); font-family:var(--font); font-size:15px;
  transition:border-color .2s ease, box-shadow .2s ease;
}
.newsletter__field input::placeholder{ color:var(--text-faint); }
.newsletter__field input:focus-visible{ outline:none; border-color:var(--accent-2); box-shadow:0 0 0 3px rgba(229,255,83,0.15); }
.newsletter__field input:disabled{ opacity:0.55; cursor:not-allowed; }
.newsletter__field .btn{ flex-shrink:0; white-space:nowrap; }
.newsletter__privacy{ margin-top:12px; font-size:12.5px; color:var(--text-faint); line-height:1.5; }
.newsletter__privacy a{ color:var(--text-faint); text-decoration:underline; }

@media(max-width:860px){
  .newsletter__inner{ grid-template-columns:1fr; gap:28px; }
}
@media(max-width:520px){
  .newsletter{ padding:48px 0; }
  .newsletter__inner{ padding:0 24px; }
  .newsletter__field{ flex-direction:column; }
  .newsletter__field .btn{ width:100%; justify-content:center; }
}

/* ---------- Client Area auth page ---------- */
.auth-page{
  min-height:100vh; display:flex; flex-direction:column;
  padding-top:140px; padding-bottom:80px;
  position:relative; overflow:hidden; background:var(--bg);
}
/* Large, low-opacity version of the same T-mark used in the nav/favicon —
   not a new asset, just referenced at scale behind the card. Purely
   decorative, never interferes with form use (z-index below the card). */
.auth-page__mark{
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
  width:min(820px, 130vw); height:auto; opacity:0.035; color:var(--text);
  pointer-events:none; z-index:0;
}
.auth-page__glow{
  position:absolute; top:8%; left:50%; transform:translateX(-50%);
  width:900px; max-width:160vw; height:460px; pointer-events:none; z-index:0;
  background:radial-gradient(ellipse 480px 260px at 50% 0%, rgba(229,255,83,0.10), transparent 70%);
}
/* Shell's own max-width/padding is just viewport-edge safety on narrow
   screens — the card's width (440-520px target) is controlled directly on
   .auth-card below, independent of this wrapper's padding math. */
.auth-shell{ position:relative; z-index:1; width:100%; max-width:560px; margin:auto; padding:0 24px; }

.auth-card{
  width:100%; max-width:480px; margin:0 auto;
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  padding:40px 36px; position:relative; overflow:hidden;
}
/* The one deliberate green accent line on the card — never a bright-green
   card fill. */
.auth-card::before{
  content:''; position:absolute; top:0; left:0; right:0; height:2px;
  background:linear-gradient(90deg, transparent, var(--accent-2), transparent);
}
.auth-card__eyebrow{
  display:inline-flex; align-items:center; gap:8px; font-size:11.5px; font-weight:700; letter-spacing:0.16em;
  text-transform:uppercase; color:var(--accent-2); margin-bottom:18px;
}
.auth-card__eyebrow::before{ content:''; width:6px; height:6px; border-radius:50%; background:var(--accent-2); box-shadow:0 0 10px var(--accent-2); }
.auth-card__title{ font-size:clamp(24px,3vw,30px); font-weight:800; letter-spacing:-0.015em; margin-bottom:10px; }
.auth-card__sub{ font-size:14.5px; color:var(--text-dim); line-height:1.55; margin-bottom:24px; }

.auth-card__status{
  display:inline-flex; align-items:center; gap:8px; font-size:11px; font-weight:800; letter-spacing:0.14em;
  text-transform:uppercase; color:var(--accent-2); background:rgba(229,255,83,0.08);
  border:1px solid rgba(229,255,83,0.3); border-radius:100px; padding:6px 14px; margin-bottom:28px;
}
.auth-card__status::before{ content:''; width:6px; height:6px; border-radius:50%; background:var(--accent-2); }

.auth-field{ margin-bottom:18px; }
.auth-field label{ display:block; font-size:13px; font-weight:600; color:var(--text-dim); margin-bottom:8px; }
.auth-field__control{ position:relative; }
.auth-field input{
  width:100%; padding:13px 16px; border-radius:10px; border:1px solid var(--border);
  background:var(--bg-alt); color:var(--text); font-family:var(--font); font-size:15px;
  transition:border-color .2s ease, box-shadow .2s ease;
}
.auth-field input::placeholder{ color:var(--text-faint); }
.auth-field input:focus-visible{ outline:none; border-color:var(--accent-2); box-shadow:0 0 0 3px rgba(229,255,83,0.15); }
.auth-field input:disabled{ opacity:0.55; cursor:not-allowed; }
.auth-field--password input{ padding-right:46px; }
.auth-field__toggle{
  position:absolute; right:6px; top:50%; transform:translateY(-50%);
  background:none; border:0; color:var(--text-faint); font-size:12.5px; font-weight:600;
  padding:6px 10px; cursor:pointer; border-radius:6px;
}
.auth-field__toggle:hover{ color:var(--text-dim); }
.auth-field__toggle:focus-visible{ outline:2px solid var(--accent-2); outline-offset:2px; }
.auth-field__toggle:disabled{ opacity:0.5; cursor:not-allowed; }

.auth-card .btn--client{ width:100%; justify-content:center; margin-top:6px; }

.auth-card__helper{ text-align:center; font-size:13px; color:var(--text-faint); margin-top:16px; line-height:1.5; }
.auth-card__links{
  display:flex; justify-content:space-between; align-items:center; margin-top:22px;
  padding-top:22px; border-top:1px solid var(--border); font-size:13.5px; flex-wrap:wrap; gap:10px;
}
.auth-card__links a{ color:var(--text-dim); }
.auth-card__links a:hover{ color:var(--accent-2); }
/* Explicit, on-brand focus ring for every plain text link across the
   Client Area surfaces — the site has no global :focus-visible rule to
   fall back on, and a default blue browser ring would clash with this
   page's palette regardless. */
.auth-card a:focus-visible,
.client-invite a:focus-visible,
.newsletter a:focus-visible{
  outline:2px solid var(--accent-2); outline-offset:2px; border-radius:2px;
}
.auth-card__privacy{ text-align:center; margin-top:20px; font-size:12px; color:var(--text-faint); }
.auth-card__privacy a{ color:var(--text-faint); text-decoration:underline; }
.auth-card__back{ text-align:center; margin-top:24px; }
.auth-card__back a{ font-size:13.5px; color:var(--text-dim); }
.auth-card__back a:hover{ color:var(--accent-2); }

@media(max-width:520px){
  .auth-card{ padding:32px 24px; }
  .auth-page{ padding-top:120px; }
}

/* ==========================================================================
   VISITOR-FIRST HOMEPAGE FLOW — prototype-only additions below. Everything
   above this point is the site's existing, unmodified design system; new
   components reuse its tokens (--accent-2, --accent, --surface, --border,
   --radius) rather than introducing a parallel palette.
   ========================================================================== */

/* ---------- Nested sub-heading (Approach, folded into How I Work) ---------- */
.section-head--nested{ max-width:680px; margin:56px 0 28px; }
.section-head--nested h3{ font-size:clamp(20px,2.6vw,24px); }
.approach__item h3, .approach__item h4{ font-size:20px; margin-bottom:12px; }

/* ---------- Visitor pathways ---------- */
.pathways__grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:1px; background:var(--border); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; }
@media(max-width:760px){ .pathways__grid{ grid-template-columns:1fr; } }
.pathway-card{ background:var(--bg); padding:32px; display:flex; flex-direction:column; }
.pathway-card h3{ font-size:20px; margin-bottom:10px; }
.pathway-card p{ font-size:15px; color:var(--text-dim); margin-bottom:18px; }
/* Quiet inline metadata — fine centred dots, not bordered pills, so four
   repeated outlines per card don't compete with the actual content. */
.pathway-card__meta{ font-size:12.5px; color:var(--text-faint); margin-bottom:24px; line-height:1.6; }
.pathway-card__meta span{ margin:0 6px; opacity:0.6; }
/* Bottom-anchored via margin-top:auto so all four links share one
   baseline regardless of copy length above. Neutral text, orange arrow
   and hover accent — green stays reserved for Client Area. */
.pathway-card__link{ margin-top:auto; display:inline-flex; align-items:center; gap:6px; color:var(--text); font-weight:600; font-size:14px; }
.pathway-card__link span{ color:var(--accent); transition:transform .2s ease; }
.pathway-card__link:hover{ color:var(--accent); }
.pathway-card__link:hover span{ transform:translateX(3px); }
.pathway-card__link:focus-visible{ outline:2px solid var(--accent-2); outline-offset:3px; border-radius:2px; }

/* ---------- Transformation (editorial FROM/TO panels) ---------- */
/* Left-aligned throughout — no centred table. A large background numeral
   sits behind the copy at low opacity so it reads as texture, not a
   competing headline; it never sits over the FROM/TO text itself. */
.shift__grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:1px; background:var(--border); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; margin-bottom:28px; }
@media(max-width:760px){ .shift__grid{ grid-template-columns:1fr; } }
.shift__panel{ position:relative; background:var(--bg); padding:36px 32px 32px; overflow:hidden; text-align:left; }
.shift__num{
  position:absolute; top:8px; right:20px; z-index:0; font-size:clamp(64px,7vw,110px); font-weight:800;
  color:var(--text); opacity:0.05; line-height:1; pointer-events:none;
}
.shift__label{
  position:relative; z-index:1; display:block; font-size:11px; font-weight:700; letter-spacing:0.12em;
  text-transform:uppercase; color:var(--text-faint); margin-bottom:6px;
}
.shift__from{ position:relative; z-index:1; color:var(--text-faint); font-size:16px; margin:0 0 18px; max-width:34ch; }
.shift__rule{ position:relative; z-index:1; display:block; width:32px; height:2px; background:var(--accent-2); margin-bottom:18px; }
.shift__to{ position:relative; z-index:1; color:var(--text); font-size:17px; font-weight:600; margin:0; max-width:34ch; }
.shift__note{ color:var(--text-dim); font-size:15px; max-width:640px; }

/* ---------- Early / selected proof ---------- */
/* One restrained visual system across all three cards: neutral charcoal
   surface, one fine border, white evidence numeral, muted eyebrow —
   orange is reserved for the final link/arrow and its hover state, and
   green doesn't appear here at all (it's a Client Area signal). Flex
   column with the link's margin-top:auto keeps the final link/arrow
   bottom-anchored on every card regardless of copy length above it. */
.proof-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:28px; align-items:stretch; }
@media(max-width:960px){ .proof-grid{ grid-template-columns:1fr; } }
.proof-card{ background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; display:flex; flex-direction:column; }
.proof-card__media{ aspect-ratio:16/10; overflow:hidden; }
.proof-card__media img{ width:100%; height:100%; object-fit:cover; display:block; }
.proof-card__body{ padding:26px; display:flex; flex-direction:column; flex:1; }
.proof-card__eyebrow{ font-size:11.5px; letter-spacing:0.1em; text-transform:uppercase; color:var(--text-faint); font-weight:700; margin-bottom:10px; }
.proof-card__body h3{ font-size:18px; margin-bottom:14px; line-height:1.35; }
.proof-card__marker{
  display:inline-block; font-size:13px; font-weight:800; letter-spacing:0.04em; color:var(--text);
  margin-bottom:16px;
}
.proof-card__body p{ font-size:14px; color:var(--text-dim); line-height:1.55; margin:0 0 12px; }
.proof-card__body p strong{ color:var(--text); font-weight:700; }
.proof-card__body p:last-of-type{ margin-bottom:0; }
/* Scoped override: the shared .work-item__more link defaults to green
   elsewhere (the full work library below) — inside these three cards it
   reads orange instead, and is pinned to the bottom of the flex column. */
.proof-card .work-item__more{ margin-top:auto; padding-top:18px; }
.proof-card .work-item__more,
.proof-card .work-item__more:hover,
.proof-card .work-item__more:focus-visible{ color:var(--text); }
.proof-card .work-item__more-arrow{ color:var(--accent); }
.proof-card .work-item__more:hover .work-item__more-arrow,
.proof-card .work-item__more:focus-visible .work-item__more-arrow{ color:#ff7256; }
.proof-card .work-item__more:focus-visible{ outline-color:var(--accent-2); }

/* ---------- Vision ---------- */
/* Text-led editorial band — Travis's portrait already lives in the hero,
   so this stays a strong statement of copy rather than a second media
   moment. Left-aligned, comfortable measure, no centred layout. */
.vision__inner{ max-width:720px; }
.vision h2{ font-size:clamp(26px,3.4vw,36px); margin-bottom:16px; line-height:1.2; text-wrap:balance; }
.vision p{ color:var(--text-dim); font-size:16px; line-height:1.6; margin-bottom:16px; max-width:62ch; text-wrap:pretty; }

/* ---------- Testimonials: progressive disclosure ---------- */
/* Order in the DOM is: initial grid, additional grid (hidden), toggle —
   so once expanded, "Show fewer" sits at the bottom of the complete set
   rather than pinned between two grids. 52px clears the toggle from
   whichever grid is currently above it, on both sides. */
/* Cards 4-9 hide via [hidden] on the card itself — no wrapping element,
   no separate margin/border, so expanding grows the same grid rather
   than revealing a visually distinct second block. */
.testi__card--more[hidden]{ display:none; }
.testi__more-toggle{
  display:flex; align-items:center; gap:8px; margin:52px auto 0; background:none; border:1px solid var(--border);
  border-radius:100px; padding:10px 20px; color:var(--text-dim); font-size:14px; font-weight:600; cursor:pointer;
  transition:border-color .2s ease, color .2s ease;
}
.testi__more-toggle:hover{ color:var(--text); border-color:var(--text-dim); }
.testi__more-toggle:focus-visible{ outline:2px solid var(--accent-2); outline-offset:3px; }

/* Restrained oversized quotation mark — an editorial cue, not a glass
   effect. Sits above the quote, low-opacity, purely decorative. */
.testi__mark{
  display:block; font-size:44px; line-height:1; font-weight:800; color:var(--accent-2);
  opacity:0.35; margin-bottom:4px; font-family:Georgia, 'Times New Roman', serif;
}

/* ---------- Closing actions ---------- */
/* Stretching grid + flex-column cards + height:100% so all three reach
   equal visual height on desktop: headings/descriptions stay top-aligned
   in .closing__card-top, and each card's action(s) sit directly below,
   at the same row across all three cards, rather than drifting to the
   card's bottom edge. .closing__card-top gets a shared min-height on
   desktop (tallest of the three copy blocks) so "Let's talk", "Enter
   client area" and the email field all line up regardless of how many
   lines each card's paragraph wraps to. One shared border/background/
   radius/padding system across all three — .closing__card--newsletter
   only adds its own form styling below, not a different card treatment. */
.closing .container{ max-width:1080px; }
.closing__head{ max-width:680px; margin-left:auto; margin-right:auto; text-align:center; }
.closing__head p{ margin-left:auto; margin-right:auto; }
.closing__grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:18px; align-items:stretch; }
@media(max-width:960px){ .closing__grid{ grid-template-columns:1fr; } }
.closing__card{
  position:relative; overflow:hidden; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:28px;
  height:100%; display:flex; flex-direction:column; justify-content:flex-start; gap:20px;
}
.closing__card h3{ font-size:20px; margin-bottom:10px; }
.closing__card-top p{ color:var(--text-dim); font-size:15px; margin:0; }
@media(min-width:961px){ .closing__card-top{ min-height:106px; } }
.closing__card-bottom{ display:flex; flex-direction:column; align-items:flex-start; }
.closing__card-extra{ display:flex; flex-wrap:wrap; gap:16px; margin-top:14px; }
/* Quiet secondary text actions — no pill background, orange hover
   accent instead of a second and third competing button. */
.closing__card-textlink{
  background:none; border:none; padding:0; color:var(--text-dim); font-size:13.5px; font-weight:600; cursor:pointer;
}
.closing__card-textlink:hover{ color:var(--accent); }
.closing__card-textlink:focus-visible{ outline:2px solid var(--accent-2); outline-offset:3px; border-radius:2px; }
.closing__card-details{ display:flex; flex-direction:column; gap:6px; margin-top:20px; font-size:13.5px; color:var(--text-faint); }
.closing__card-details a{ color:var(--text-dim); }
.closing__card-note{ margin-top:14px; color:var(--text-faint); font-size:12.5px; line-height:1.5; }
.reveal--closing:nth-child(2){ transition-delay:.08s; }
.reveal--closing:nth-child(3){ transition-delay:.16s; }
.closing__card--newsletter .newsletter__status{
  display:inline-flex; align-items:center; gap:8px; font-size:11px; font-weight:800; letter-spacing:0.14em;
  text-transform:uppercase; color:var(--text-dim); background:rgba(255,255,255,0.04);
  border:1px solid var(--border); border-radius:100px; padding:6px 14px; margin-top:14px;
}
.closing__card--newsletter .newsletter__status::before{ content:''; width:6px; height:6px; border-radius:50%; background:var(--text-dim); display:inline-block; }
.closing__card--newsletter .newsletter__field{ display:flex; gap:10px; }
.closing__card--newsletter .newsletter__field input{
  flex:1; min-width:0; padding:13px 16px; border-radius:10px; border:1px solid var(--border);
  background:var(--bg); color:var(--text); font-family:var(--font); font-size:15px;
}
.closing__card--newsletter .newsletter__field input::placeholder{ color:var(--text-faint); }
.closing__card--newsletter .newsletter__field input:focus-visible{ outline:none; border-color:var(--accent-2); box-shadow:0 0 0 3px rgba(229,255,83,0.15); }
.closing__card--newsletter .newsletter__field input:disabled{ opacity:0.55; cursor:not-allowed; }
.closing__card--newsletter .newsletter__privacy{ margin-top:12px; font-size:12.5px; color:var(--text-faint); line-height:1.5; }
.closing__card--newsletter .newsletter__privacy a{ color:var(--text-faint); text-decoration:underline; }
@media(max-width:480px){ .closing__card--newsletter .newsletter__field{ flex-direction:column; } }
@media(max-width:640px){
  .closing__head{ text-align:left; }
  .closing__card{ padding:24px; }
  .footer__row{ align-items:flex-start; }
  .footer__links{ justify-content:flex-start; gap:12px 18px; }
  .reveal--green-rule{ padding-left:18px; }
}

.pathway-card a:focus-visible,
.proof-card a:focus-visible,
.closing__card a:focus-visible,
.vision a:focus-visible{ outline:2px solid var(--accent-2); outline-offset:2px; border-radius:2px; }

/* ---------- Reduced motion ---------- */
/* Keeps opacity/colour fades (they aid comprehension) but strips
   transform-based movement — scroll-reveal slide, card flip, marquee,
   pulsing route dots, button lift/press — for anyone with
   prefers-reduced-motion set at the OS level. */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  .reveal{ transition:opacity .3s ease; transform:none; }
  [data-depth]{ transform:none !important; }
  .flip-card,.flip-card:hover{ transform:none !important; filter:none !important; transition:none; }
  .flip-card__inner{ transition:none; }
  .reveal--green-rule::before{ transition:none; transform:none; }
  .route__dot{ animation:none; }
  /* Carousel stops entirely and becomes a manually-scrollable strip
     instead — the animation is removed, not just paused. */
  .marquee.is-ready{ animation:none; }
  .orgs__wrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .stack-panel{ transition:none; }
  .stack-panel:hover{ transform:none !important; }
  .media-stage__play{ transition:none; }
  .media-stage__play:hover{ transform:translate(-50%,-50%) !important; }
  .btn, .btn:active, .btn--primary:hover, .btn--ghost:hover, .btn--icon:hover{ transform:none !important; }
  .client-invite__cta:hover{ transform:none !important; box-shadow:none !important; }
  .auth-card__glow{ animation:none !important; }
  .btn::before{ animation:none !important; opacity:0 !important; }
  .loader__comet, .loader__bloom, .loader__spot{ animation:none !important; }
  .loader{ transition:opacity .3s ease; }
  .work-item__plus, .reel-facade__play, .reel-facade img{ transition:none; transform:none !important; }
  .carousel__slide{ transition:none; }
  .kinetic-tag__word{ animation:none !important; opacity:0 !important; }
  .kinetic-tag__word:first-child{ opacity:1 !important; transform:none !important; }
  .work-item__more-arrow{ transition:none; }
}
