/* ============ TENIVISION, SHARED STYLES ============ */
:root{
  /* GROUND IS PURE: black in dark, white in light. The raised tokens sit just
     off it — note the relationship INVERTS between themes. On black, a card is
     LIGHTER than the page; on white it has to be DARKER, because there is
     nothing above #fff. Getting this backwards makes every card vanish. */
  --bg:#000; --bg2:#111113; --bg3:#17171a; --band:#0a0a0c;
  --ink:#f4f1ec; --muted:#9a958d; --faint:#6b6862;
  --line:rgba(255,255,255,.09); --line2:rgba(255,255,255,.06);
  --accent:#ff4d1c; --accent-soft:#ff6b3d; --gold:#f5b301;
  --maxw:1180px; --r:12px;
  /* ONE radius scale, tightened against magnific.com (its corners are noticeably
     squarer than what this site had): 6px micro-labels and tags - 8px chips and
     small controls - 10px buttons, inputs, mid panels - var(--r) 12px cards -
     16px large media surfaces. 50% stays for true circles. The only deliberate
     capsules left are the WhatsApp FAB, the mock phone notch and the carousel dot. */
  --serif:'Syne',sans-serif; --sans:'Inter',system-ui,sans-serif;

  /* ONE TYPE SCALE FOR EVERY SECTION HEADING AND ITS SUB-LINE.
     These are the homepage hero's own values ("Be impossible to ignore." and
     the line under it) promoted to tokens, because the client wants every
     other header and sub-text to match that pair rather than each section
     carrying its own clamp. Change them here, not at the call sites.
     In-body headings (.post-body h2, .legal h2) and card titles are NOT on
     this scale — they are not section headers. */
  /* Sized against magnific.com, which runs its section headings at 44px on a
     1400 viewport. Syne is a much WIDER face at the same pixel size, so matching
     their number still reads slightly larger — that is intentional headroom, not
     an oversight. 3.05vw lands on ~42.7px at 1400. */
  --fs-h:clamp(1.6rem,3.05vw,2.7rem); --lh-h:1.04;
  --fs-sub:clamp(.94rem,1.08vw,1.04rem); --lh-sub:1.58;
}
@media(max-width:640px){:root{--fs-h:min(7vw,1.72rem); --lh-h:1.08}}
:root[data-theme="light"]{
  --bg:#fff; --bg2:#f7f7f8; --bg3:#ededef; --band:#f0f0f3;
  --ink:#141311; --muted:#5c574f; --faint:#8a857b;
  --line:rgba(0,0,0,.11); --line2:rgba(0,0,0,.06);
}
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;overflow-x:clip;max-width:100%}
body{background:var(--bg);color:var(--ink);font-family:var(--sans);font-weight:300;line-height:1.6;
  overflow-x:clip;max-width:100%;-webkit-font-smoothing:antialiased;transition:background .5s,color .5s}
img,video{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
/* content protection: no text selection, no image drag/long-press save */
*{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none}
input,textarea,select,[contenteditable]{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}
img{-webkit-user-drag:none;-khtml-user-drag:none;-moz-user-drag:none;-o-user-drag:none;user-drag:none}
::selection{background:var(--accent);color:#fff}

/* ---- keyboard focus ----
   Every input rule on this page sets outline:none, and nothing put one back, so
   tabbing through the site was invisible. :focus-visible only paints for keyboard
   and other non-pointer input, so mouse users never see a ring. */
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}
.btn:focus-visible,.chip:focus-visible,.copy-btn:focus-visible{outline-offset:3px}
.field input:focus-visible,.field textarea:focus-visible,.field select:focus-visible{outline-offset:0}

/* skip link: off-screen until focused, then pinned under the fixed bar */
.skip-link{position:fixed;top:8px;left:-9999px;z-index:200;padding:10px 18px;border-radius:8px;
  background:var(--accent);color:#fff;font-size:.86rem;font-weight:600}
.skip-link:focus{left:8px}
:is(section,main)[tabindex="-1"]:focus{outline:none}   /* target lands, no stray ring */
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px}
h1,h2,h3,.dsp{font-family:var(--serif);font-weight:700;line-height:1.02;letter-spacing:-.02em}
.eyebrow{font-family:var(--sans);font-weight:600;font-size:.72rem;letter-spacing:.22em;text-transform:uppercase;color:var(--accent)}
.muted{color:var(--muted)}
.sec-num{font-family:var(--serif);color:var(--faint);font-size:.8rem;letter-spacing:.1em}

/* backdrop — NOTHING PAINTS BEHIND THE PAGE ANY MORE.
   Three layers used to: the orange/purple .glow blobs, the .grain noise overlay,
   and a slanted intersecting grid on body::before. All removed on request, and
   their markup is gone from every page too. The ground is now exactly --bg:
   pure black in dark, pure white in light. Do not reintroduce a backdrop here
   without asking — this was a deliberate call, twice. */

/* nav */
header.nav{position:fixed;top:0;left:0;right:0;z-index:50;
  background:linear-gradient(180deg,rgba(14,14,16,.84),rgba(0,0,0,.76));
  border-bottom:1px solid rgba(255,255,255,.08);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14),inset 0 -1px 0 rgba(255,255,255,.04),0 10px 30px -20px rgba(0,0,0,.6);
  /* PERF: was saturate(200%) blur(22px) brightness(1.08) — three filter passes redone on
     every scroll frame, on every page. One modest blur over a more opaque ground reads
     the same. Don't stack backdrop-filters on anything INSIDE this bar. */
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);transition:background .3s,box-shadow .3s,border-color .3s}
:root[data-theme="light"] header.nav{background:linear-gradient(180deg,rgba(255,255,255,.92),rgba(255,255,255,.86));
  border-bottom-color:rgba(0,0,0,.06);box-shadow:inset 0 1px 0 rgba(255,255,255,.8),inset 0 -1px 0 rgba(0,0,0,.03),0 10px 30px -20px rgba(0,0,0,.15)}
/* full-bleed bar: logo hard left, links beside it, controls hard right */
.nav-in{display:grid;grid-template-columns:auto 1fr auto;align-items:center;max-width:none;margin:0 auto;
  padding:0 clamp(18px,2.6vw,44px);height:46px;transition:.3s}
.nav-in>.brand{justify-self:start}
.nav-in>.nav-links:not(.main){justify-self:end}
.nav.scrolled{box-shadow:0 6px 24px -14px rgba(0,0,0,.4)}
.brand{display:flex;align-items:center;gap:0;font-family:var(--serif);font-weight:800;font-size:.88rem;letter-spacing:-.01em}
.brand .mk{width:28px;height:28px;border-radius:6px;background:var(--accent);color:#fff;display:grid;place-items:center;
  font-size:1rem;box-shadow:0 4px 16px rgba(255,77,28,.4)}
.brand .mk-img{height:16px;width:auto;margin-right:7px;border-radius:0;display:block;box-shadow:none}
:root[data-theme="light"] .brand .mk-img{filter:invert(1)}
.foot-brand .brand .mk-img{height:28px;margin-right:9px}
.brand b{color:var(--ink)} .brand span{color:var(--accent)}
.nav-links{display:flex;gap:4px;align-items:center}
/* Apple-style centred, evenly-spread links spanning the bar */
.nav-links.main{justify-content:flex-start;gap:clamp(14px,2.2vw,34px);margin-left:clamp(18px,3.2vw,52px)}
.nav-links a{font-family:var(--sans);font-weight:400;font-size:.8rem;letter-spacing:.01em;color:var(--ink);
  opacity:.82;padding:6px 2px;border-radius:0;transition:opacity .2s,color .2s}
.nav-links a:hover{opacity:1;color:var(--ink);background:none}
.nav-links a.current{opacity:1;color:var(--ink)}
/* theme toggle visible in nav (auto day/night sets the initial value) */
.nav-cta{font-family:var(--sans);font-weight:500;font-size:.8rem;background:none;padding:6px 2px!important;border-radius:0;opacity:1;transition:opacity .2s}
.nav-cta:hover{transform:none;opacity:.68}
/* keep the gradient text fill on hover (generic .nav-links a:hover sets background:none, which would erase the clipped gradient and make the text vanish) */
.nav-links a.nav-cta:hover{background:linear-gradient(120deg,var(--accent),var(--gold));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;opacity:.68}
.icon-btn{width:38px;height:38px;border-radius:50%;border:1px solid rgba(255,255,255,.16);color:var(--ink);
  background:linear-gradient(160deg,rgba(255,255,255,.14),rgba(255,255,255,.03));
  box-shadow:inset 0 1px 1px rgba(255,255,255,.4),inset 0 -3px 8px -5px rgba(255,255,255,.25),0 4px 12px -6px rgba(0,0,0,.5);
  display:grid;place-items:center;cursor:pointer;transition:.25s}
.icon-btn:hover{background:linear-gradient(160deg,rgba(255,255,255,.24),rgba(255,255,255,.08));transform:translateY(-1px)}
.icon-btn svg{width:18px;height:18px}
:root[data-theme="light"] .icon-btn{border-color:rgba(0,0,0,.1);
  background:linear-gradient(160deg,rgba(255,255,255,.7),rgba(255,255,255,.45));
  box-shadow:inset 0 1px 1px rgba(255,255,255,.9),inset 0 -3px 8px -5px rgba(0,0,0,.05),0 4px 12px -6px rgba(0,0,0,.15)}
:root[data-theme="light"] .icon-btn:hover{background:linear-gradient(160deg,rgba(255,255,255,.9),rgba(255,255,255,.6))}
.burger{display:none}
@media(max-width:860px){
  /* drop backdrop-filter so it doesn't become the containing block for the fixed overlay */
  header.nav{background:rgba(0,0,0,.94);backdrop-filter:none;-webkit-backdrop-filter:none}
  :root[data-theme="light"] header.nav{background:rgba(255,255,255,.96)}
  .burger{display:grid}
  /* brand hard-left, controls hard-right. The fixed overlay is out of flow,
     so the 3-col grid was auto-placing the icon cluster into the MIDDLE column
     and leaving the right third empty - flex fixes the balance. */
  .nav-in{display:flex;align-items:center;justify-content:space-between;gap:12px}
  .desktop-only{display:none!important}
  /* the wordmark and the controls stay above the overlay, so the burger is always
     reachable to close it and the header still identifies itself */
  .nav-in>.brand,.nav-in>.nav-links:not(.main){position:relative;z-index:70}

  /* DROP-DOWN PANEL (was a full-screen overlay). header.nav is position:fixed, so
     it is this panel's containing block — top:100% parks it directly under the bar
     and it is only as tall as its links. It slides DOWN on open and back UP on
     close; anything outside it (tap, scroll, swipe up, Escape) closes it. */
  .nav-links.main{position:absolute;top:100%;left:0;right:0;z-index:60;
    display:block;margin:0;padding:4px 0 6px;
    background:var(--bg);border-bottom:1px solid var(--line);
    box-shadow:0 18px 40px -22px rgba(0,0,0,.55);
    opacity:0;visibility:hidden;transform:translateY(-10px);
    transition:opacity .24s ease,transform .28s cubic-bezier(.16,1,.3,1),visibility 0s .28s}
  .nav-links.main.open{opacity:1;visibility:visible;transform:none;
    transition:opacity .24s ease,transform .28s cubic-bezier(.16,1,.3,1),visibility 0s}
  .nav-links.main a{display:block;width:auto;text-align:left;
    font-family:var(--sans);font-weight:500;font-size:1rem;letter-spacing:0;line-height:1.3;
    color:var(--ink);opacity:.9;background:none;border-radius:0;
    padding:15px 22px;border-bottom:1px solid var(--line2);
    transform:none;transition:color .2s,opacity .2s}
  .nav-links.main a:last-child{border-bottom:0}
  .nav-links.main a:hover,.nav-links.main a:active,
  .nav-links.main a.current,
  :root[data-theme="light"] .nav-links.main a:hover,
  :root[data-theme="light"] .nav-links.main a.current{opacity:1;background:none;color:var(--accent)}
  /* "Start a project" is not in the phone menu — removed on request */
  .nav-links.main .nav-cta{display:none}
}

/* buttons */
.btn{display:inline-flex;align-items:center;gap:10px;font-family:var(--sans);font-weight:600;font-size:.92rem;
  padding:14px 24px;border-radius:10px;cursor:pointer;transition:.28s;border:1px solid transparent}
.btn-primary{background:var(--accent);color:#fff}
.btn-primary:hover{background:var(--accent-soft);transform:translateY(-2px);box-shadow:0 12px 30px rgba(255,77,28,.35)}
.btn-ghost{border-color:var(--line);color:var(--ink);background:var(--bg2)}
.btn-ghost:hover{border-color:var(--ink);transform:translateY(-2px)}
.btn svg{width:17px;height:17px}

/* section shell */
.sec-pad{padding:96px 0}
.sec-head{margin-bottom:52px;max-width:640px}
.sec-head h2{font-size:var(--fs-h);line-height:var(--lh-h);margin:14px 0 16px}
.sec-head p{color:var(--muted);font-size:var(--fs-sub);line-height:var(--lh-sub)}

/* "What we do" — heading left, scrolling wall of what we make on the right */
.wd-head{display:flex;align-items:center;gap:56px;margin-bottom:52px}
.wd-head .sec-head{margin-bottom:0;flex:1 1 auto}
.wd-wall{flex:0 0 clamp(380px,42%,470px);min-width:0;max-width:100%;display:flex;flex-direction:column;gap:14px;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 20%,#000 80%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 20%,#000 80%,transparent)}
.wd-row{overflow:hidden;min-width:0}
.wd-track{display:flex;gap:14px;width:max-content;will-change:transform}
.wd-track.left{animation:wdLeft 30s linear infinite}
.wd-track.right{animation:wdRight 30s linear infinite}
.wd-track.slow{animation-duration:42s}
.wd-wall:hover .wd-track{animation-play-state:paused}
.wd-chip{flex:0 0 auto;white-space:nowrap;font-family:var(--serif);font-weight:600;font-size:1rem;
  padding:12px 22px;border-radius:10px;background:var(--bg2);border:1px solid var(--line2);color:var(--ink)}
.wd-chip.hot{background:linear-gradient(135deg,var(--accent),var(--gold));border-color:transparent;color:#fff;
  box-shadow:0 6px 18px rgba(255,77,28,.28)}
@keyframes wdLeft{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@keyframes wdRight{from{transform:translateX(-50%)}to{transform:translateX(0)}}
@media(max-width:900px){
  .wd-head{flex-direction:column;align-items:flex-start;gap:34px}
  .wd-wall{flex-basis:auto;width:100%}
}

/* Banded sections need their OWN shade, not --bg2: cards on them are --bg2,
   so a band painted --bg2 made every card inside it invisible. --band sits
   between the ground and the cards, keeping ground < band < card in both
   themes. */
.tint{background:var(--band);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}

/* page hero (subpages) */
.page-hero{padding:150px 0 60px;position:relative;text-align:center}
.page-hero .eyebrow{display:block;margin-bottom:18px}
.page-hero h1{font-size:var(--fs-h);line-height:var(--lh-h);font-weight:800;overflow-wrap:break-word}
.page-hero h1 .em{font-style:normal;background:linear-gradient(120deg,var(--accent),var(--gold));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.page-hero p{color:var(--muted);font-size:var(--fs-sub);line-height:var(--lh-sub);max-width:52ch;margin:22px auto 0}
.crumb{display:inline-flex;gap:8px;align-items:center;font-size:.8rem;color:var(--faint);margin-bottom:20px}
.crumb a:hover{color:var(--accent)} .crumb span{color:var(--accent)}
/* phones: the fixed bar is only 46px tall, so a 150px hero top-pad left a wide
   empty band above the breadcrumb on every inner page. Tighten the whole stack
   so the title starts near the top of the screen instead of a third down. */
@media(max-width:760px){
  .page-hero{padding:88px 0 34px}
  .page-hero .eyebrow{margin-bottom:11px}
  .page-hero .crumb{margin-bottom:12px}
  .page-hero p{margin-top:16px}
}
@media(max-width:480px){
  .page-hero{padding:78px 0 28px}
}

/* home hero */
.hero{position:relative;padding:150px 0 70px;overflow:hidden}
.hero-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:44px;align-items:center}
.hero-tag{display:inline-flex;align-items:center;gap:5px;
  font-size:.52rem;letter-spacing:.22em;text-transform:uppercase;color:var(--muted);margin-bottom:26px}
.hero h1{font-size:clamp(2.4rem,6.6vw,4.8rem);font-weight:800;margin-bottom:20px}
.hero h1 .em{font-style:normal;background:linear-gradient(120deg,var(--accent),var(--gold));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.hero-role{font-size:1.05rem;color:var(--ink);font-weight:400;margin-bottom:14px}
.hero-role b{color:var(--accent);font-weight:600}
.hero-desc{font-size:1.02rem;color:var(--muted);max-width:33ch;margin-bottom:32px}
.hero-btns{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:38px}
.hero-stats{display:flex;gap:34px;flex-wrap:wrap}
.hstat .n{font-family:var(--serif);font-weight:700;font-size:1.9rem;line-height:1}
.hstat .n span{color:var(--accent)}
.hstat .l{font-size:.78rem;color:var(--muted);margin-top:5px;letter-spacing:.02em}
.hero-photo{position:relative;justify-self:center}
.photo-frame{position:relative;width:min(360px,80vw);aspect-ratio:4/5;border-radius:16px;overflow:hidden;
  border:1px solid var(--line);box-shadow:0 40px 90px rgba(0,0,0,.5)}
.photo-frame img{width:100%;height:100%;object-fit:cover;filter:saturate(1.05)}
.photo-frame::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 55%,rgba(0,0,0,.55))}
.photo-badge{position:absolute;bottom:16px;left:16px;right:16px;z-index:2;display:flex;align-items:center;justify-content:space-between;
  padding:12px 16px;border-radius:10px;background:rgba(12,12,14,.6);backdrop-filter:blur(10px);border:1px solid var(--line)}
.photo-badge .nm{font-family:var(--serif);font-weight:700;font-size:1rem;color:#fff}
.photo-badge .loc{font-size:.74rem;color:#c9c4bb}
.photo-orb{position:absolute;width:88px;height:88px;border-radius:50%;background:var(--accent);display:grid;place-items:center;
  top:-24px;right:-18px;color:#fff;font-family:var(--serif);font-weight:700;font-size:.72rem;text-align:center;line-height:1.2;
  box-shadow:0 14px 34px rgba(255,77,28,.45);animation:spinorb 18s linear infinite}
@keyframes spinorb{to{transform:rotate(360deg)}}
.photo-orb span{animation:spinorb 18s linear infinite reverse}
@media(max-width:860px){
  .hero{padding:120px 0 40px} .hero-grid{grid-template-columns:1fr;gap:40px}
  .hero-photo{order:-1} .hero-desc{max-width:none}
}
/* centered (no-graphic) hero */
.hero-solo{padding:180px 0 90px;text-align:center}
.hero-solo .hero-copy{max-width:880px;margin:0 auto}
.hero-solo .hero-tag{margin-bottom:26px}
.hero-solo .hero-desc{max-width:58ch;margin-left:auto;margin-right:auto}
.hero-solo .hero-btns{justify-content:center}
.hero-solo .hero-stats{justify-content:center;gap:clamp(28px,6vw,52px)}
@media(max-width:860px){.hero-solo{padding:132px 0 54px}}

/* hero background image: a crowd with every hand in the air — attention, proven.
   Dimmed and vignetted so the headline stays the loudest thing on screen. */
.hero-img{position:relative;isolation:isolate}
.hero-bg{position:absolute;inset:0;z-index:-1;overflow:hidden;pointer-events:none;background:#000}
/* screen blend drops the photo's black — only the warm light-trails remain, over our own dark base, so it reads the same in either theme */
.hero-bg img{width:100%;height:100%;object-fit:cover;object-position:center 38%;mix-blend-mode:screen}
/* dark scrim + edge fade so text sits on calm darkness and the image melts into the page bg */
.hero-bg::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(0,0,0,.82) 0%,rgba(0,0,0,.6) 42%,rgba(0,0,0,.78) 78%,var(--bg) 100%),
             radial-gradient(ellipse at center 40%,transparent 0%,rgba(0,0,0,.55) 100%)}
/* image is warm/dark by nature — keep text light in BOTH themes inside the hero */
.hero-img .hero-tag{color:#cfc9c0}
.hero-img h1{color:#f4f1ec}
.hero-img .hero-desc{color:#b5afa5}
.hero-img .hstat .l{color:#a49e94}
.hero-img .btn-ghost{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.22);color:#f4f1ec}
.hero-img .btn-ghost:hover{border-color:#f4f1ec}
/* ===== light theme: warm-on-white hero (own photo, light scrim, dark text) =====
   the light photo is warm trails on WHITE, so multiply drops the white and keeps
   the trails/shadows over our light base — the mirror of screen-on-black above */
.hero-bg-light{display:none}
:root[data-theme="light"] .hero-bg{background:var(--bg)}
:root[data-theme="light"] .hero-bg-dark{display:none}
:root[data-theme="light"] .hero-bg-light{display:block;mix-blend-mode:multiply;opacity:.6}
:root[data-theme="light"] .hero-bg::after{
  background:linear-gradient(180deg,rgba(255,255,255,.72) 0%,rgba(255,255,255,.5) 42%,rgba(255,255,255,.85) 84%,var(--bg) 100%),
             radial-gradient(ellipse at center 42%,rgba(255,255,255,.32) 0%,rgba(255,255,255,.62) 100%)}
:root[data-theme="light"] .hero-img .hero-tag{color:var(--muted)}
:root[data-theme="light"] .hero-img h1{color:var(--ink)}
:root[data-theme="light"] .hero-img .hero-desc{color:var(--muted)}
:root[data-theme="light"] .hero-img .hstat .l{color:var(--muted)}
:root[data-theme="light"] .hero-img .btn-ghost{background:rgba(0,0,0,.04);border-color:rgba(0,0,0,.14);color:var(--ink)}
:root[data-theme="light"] .hero-img .btn-ghost:hover{border-color:var(--ink)}

/* ---- cinematic hero: one full-screen frame, copy left, rotating capability list right ----
   The photograph runs edge to edge behind a transparent nav; everything sits on it.
   The scrim is directional — heaviest on the left where the words are, lighter on the
   right so the picture still reads as a picture. */
/* Height is CAPPED, not a full 100svh. The reference fills its lower third with a
   trusted-by logo strip; we deliberately have none, so a full-viewport hero left ~330px
   of empty photograph under the buttons on a 1080-tall screen. Capping tightens the
   composition and lets the marquee peek in as a scroll cue.
   Cap tightened again 2026-09-02: at 82svh/840px the copy (~346px) still floated in the
   middle of a 738px band, ~174px of empty photograph above it and ~171px below. The band
   is centred, so EVERY extra pixel of height buys two pixels of dead space — hence a
   lower cap plus asymmetric padding (more on top to clear the transparent nav). */
.hero-cine{min-height:clamp(520px,62svh,620px);display:flex;align-items:center;
  padding:clamp(92px,9.5vh,116px) 0 clamp(56px,6.5vh,84px);text-align:left}
.hero-cine .hero-in{width:min(1160px,70vw);max-width:calc(100% - 48px);margin:0 auto;
  display:grid;grid-template-columns:minmax(0,1fr) max-content;align-items:center;
  gap:clamp(30px,5vw,86px)}
.hero-cine .hero-copy{max-width:none;min-width:0}

.hero-cine .hero-bg::after{
  background:
    linear-gradient(90deg,rgba(0,0,0,.93) 0%,rgba(0,0,0,.82) 34%,rgba(0,0,0,.64) 66%,rgba(0,0,0,.6) 100%),
    linear-gradient(180deg,rgba(0,0,0,.7) 0%,rgba(0,0,0,.1) 22%,rgba(0,0,0,.16) 70%,var(--bg) 100%)}
:root[data-theme="light"] .hero-cine .hero-bg::after{
  background:
    linear-gradient(90deg,rgba(255,255,255,.9) 0%,rgba(255,255,255,.76) 34%,rgba(255,255,255,.6) 66%,rgba(255,255,255,.58) 100%),
    linear-gradient(180deg,rgba(255,255,255,.6) 0%,rgba(255,255,255,.12) 22%,rgba(255,255,255,.2) 70%,var(--bg) 100%)}

/* the little claim pill above the headline */
.hero-badge{display:inline-flex;align-items:center;gap:10px;margin-bottom:clamp(18px,3vh,30px);
  padding:11px 16px;border-radius:10px;font-family:var(--sans);font-size:.8rem;white-space:nowrap;
  border:1px solid rgba(255,255,255,.18);background:rgba(22,19,16,.62);transition:.25s}
.hero-badge:hover{background:rgba(30,26,22,.78);border-color:rgba(255,255,255,.32)}
.hero-cine .hero-badge b.hero-tag{display:inline;margin:0;font-weight:600;letter-spacing:0;
  text-transform:none;font-size:inherit;color:#f4f1ec;-webkit-text-fill-color:#f4f1ec}
.hero-badge span{color:rgba(244,241,236,.62);padding-right:2px}
.hero-badge svg{width:15px;height:15px;flex:0 0 auto;color:var(--accent);transition:transform .25s}
.hero-badge:hover svg{transform:translateX(3px)}
:root[data-theme="light"] .hero-badge{border-color:rgba(0,0,0,.12);background:rgba(255,255,255,.74)}
:root[data-theme="light"] .hero-badge:hover{background:rgba(255,255,255,.9);border-color:rgba(0,0,0,.22)}
:root[data-theme="light"] .hero-cine .hero-badge b.hero-tag{color:var(--ink);-webkit-text-fill-color:var(--ink)}
:root[data-theme="light"] .hero-badge span{color:var(--muted)}

/* body.re carries the site-wide display sizing, so match its weight to sit under it */
body.re .hero.hero-cine h1{font-size:clamp(1.85rem,3.3vw,3.05rem);line-height:1.05;
  margin-bottom:clamp(16px,2.4vh,24px);max-width:16ch}
body.re .hero-cine .hero-desc{font-size:var(--fs-sub);line-height:var(--lh-sub);
  max-width:58ch;margin-bottom:clamp(24px,3.6vh,38px)}
.hero-cine .hero-btns{margin-bottom:0;gap:14px}

/* solid + outlined pair, both readable straight on the photograph */
.btn-hero,.btn-hero-ghost{border-radius:10px;padding:15px 24px}
.btn-hero{background:#f4f1ec;color:#141311;border-color:transparent}
.btn-hero:hover{background:#fff;transform:translateY(-2px);box-shadow:0 14px 32px -12px rgba(0,0,0,.55)}
.btn-hero-ghost{background:rgba(22,19,16,.6);border-color:rgba(255,255,255,.26);color:#f4f1ec}
.btn-hero-ghost:hover{background:rgba(30,26,22,.8);border-color:#f4f1ec;transform:translateY(-2px)}
.btn-hero-ghost svg{width:13px;height:13px}
/* phones: the pair was still carrying desktop padding, so two buttons ate a
   third of the hero. Scaled with the rest of the phone hero, not fixed. */
@media(max-width:640px){
  .hero-cine .hero-btns{gap:10px}
  .btn-hero,.btn-hero-ghost{padding:11px 17px;font-size:.82rem;gap:8px}
  .btn-hero svg,.btn-hero-ghost svg{width:12px;height:12px}
}
@media(max-width:380px){
  .btn-hero,.btn-hero-ghost{padding:10px 14px;font-size:.78rem}
}
:root[data-theme="light"] .btn-hero{background:var(--ink);color:var(--bg2)}
:root[data-theme="light"] .btn-hero:hover{background:#000}
:root[data-theme="light"] .btn-hero-ghost{background:rgba(255,255,255,.76);border-color:rgba(0,0,0,.16);color:var(--ink)}
:root[data-theme="light"] .btn-hero-ghost:hover{background:rgba(255,255,255,.85);border-color:var(--ink)}

/* the capability list: the marker never moves — the column travels up under it,
   so each promise walks into the light in turn. Rows are a fixed height because the
   scroll maths counts in whole rows, and the window is an odd number of them so
   there is a true middle row for the marker to sit on. */
.hero-list{--row:clamp(2.1rem,3.6vh,2.9rem);
  position:relative;overflow:hidden;contain:layout paint;height:calc(var(--row)*7);padding-left:30px;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 15%,#000 85%,transparent 100%);
          mask-image:linear-gradient(180deg,transparent 0,#000 15%,#000 85%,transparent 100%)}
.hero-list-track{list-style:none;margin:0;padding:0;will-change:transform;
  transition:transform .62s cubic-bezier(.35,0,.15,1)}
.hero-list-track li{height:var(--row);display:flex;align-items:center;white-space:nowrap;
  font-family:var(--serif);font-weight:700;letter-spacing:-.02em;line-height:1.1;
  font-size:clamp(1.05rem,1.9vw,1.6rem);
  color:rgba(244,241,236,.32);transition:color .5s ease}
.hero-list-track li.on{color:#fff}
.hero-list-mark{position:absolute;left:0;top:50%;margin-top:-6.5px;
  width:0;height:0;border-left:10px solid var(--accent);
  border-top:6.5px solid transparent;border-bottom:6.5px solid transparent}
:root[data-theme="light"] .hero-list-track li{color:rgba(20,19,17,.3)}
:root[data-theme="light"] .hero-list-track li.on{color:var(--ink)}

/* nav sits on the picture until the page moves */
body.has-cine header.nav:not(.scrolled):not(.menu-open){background:transparent;border-bottom-color:transparent;
  box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none}
/* while the list animates behind them, anything sampling the backdrop strobes -
   the icon buttons get a flat panel until the bar goes solid on scroll */
body.has-cine header.nav:not(.scrolled):not(.menu-open) .icon-btn{backdrop-filter:none;-webkit-backdrop-filter:none;
  background:rgba(22,19,16,.55);border-color:rgba(255,255,255,.18)}
:root[data-theme="light"] body.has-cine header.nav:not(.scrolled):not(.menu-open) .icon-btn{
  background:rgba(255,255,255,.7);border-color:rgba(0,0,0,.12)}
body.has-cine header.nav:not(.scrolled):not(.menu-open) .nav-in>.brand,
body.has-cine header.nav:not(.scrolled):not(.menu-open) .nav-links.main>a:not(.nav-cta),
body.has-cine header.nav:not(.scrolled):not(.menu-open) .icon-btn{color:#f4f1ec}
:root[data-theme="light"] body.has-cine header.nav:not(.scrolled):not(.menu-open) .nav-in>.brand,
:root[data-theme="light"] body.has-cine header.nav:not(.scrolled):not(.menu-open) .nav-links.main>a:not(.nav-cta),
:root[data-theme="light"] body.has-cine header.nav:not(.scrolled):not(.menu-open) .icon-btn{color:var(--ink)}

/* THE CAPABILITY COLUMN NEVER STACKS — it stays beside the copy on the right at
   every width it is SHOWN at. On phones (<=640) it is not shown at all; see that
   block below. The bug this fixes was the tablet range, where it used to drop
   underneath the buttons.
   The desktop track is `max-content`, which lets the longest promise set the
   column width — fine at 1440, fatal at 390 (it would push the copy off-screen).
   So from 980 down the split becomes PROPORTIONAL and the list type scales with
   the viewport instead of the content. Rows shrink with it, because the scroll
   maths counts whole rows and the window must stay an odd row count to keep a
   true middle for the marker. */
@media(max-width:980px){
  .hero-cine .hero-in{width:100%;max-width:var(--maxw);padding:0 24px;
    grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);gap:clamp(18px,3.4vw,40px)}
  .hero-cine h1{max-width:none}
  .hero-list{height:calc(var(--row)*5);padding-left:24px}
  /* both halves cannot share one line once the copy column is this narrow */
  .hero-badge span{display:none}
  .hero-list-track li{font-size:clamp(.92rem,2.2vw,1.3rem)}
}
@media(max-width:760px){
  .hero-cine .hero-in{grid-template-columns:minmax(0,1.12fr) minmax(0,.88fr);
    gap:14px;padding:0 20px}
  .hero-list{--row:clamp(1.72rem,4.4vw,2.2rem);height:calc(var(--row)*3);padding-left:17px}
  .hero-list-track li{font-size:clamp(.78rem,2.9vw,1.05rem)}
  .hero-list-mark{border-left-width:8px;border-top-width:5.5px;border-bottom-width:5.5px;margin-top:-5.5px}
}

/* phone: the window narrows to a single row, so it reads as one rotating promise */
@media(max-width:640px){
  /* On a phone the hero is CONTENT-HEIGHT. The capped min-height was written for
     the two-column desktop composition; stacked, the copy is far shorter than
     82svh, so centring it left ~94px of empty photograph above the badge and
     ~88px below the list. Padding alone now sets the frame: enough to clear the
     transparent nav on top, a normal section gap underneath. */
  .hero-cine{min-height:auto;padding:clamp(74px,10vh,92px) 0 clamp(30px,4.5vh,46px)}
  /* PHONES DO NOT GET THE ROTATING LIST AT ALL. There is no width here at which
     it can sit beside the copy without starving both columns, and stacked it
     reads as a stray line of text that changes by itself. JS is left running —
     the list is only hidden — so rotation resumes above 640px.
     With it gone the copy takes the full width back, so the grid collapses to
     one column and the headline returns to its full phone size. */
  .hero-list{display:none}
  .hero-cine .hero-in{grid-template-columns:minmax(0,1fr);gap:0}
  body.re .hero.hero-cine h1{font-size:min(7vw,1.75rem);line-height:1.08}
  /* the pill keeps only its claim on a phone, exactly as the reference does —
     both halves cannot share one line at this width, and it wraps into a block */
  .hero-badge{padding:9px 13px;font-size:.74rem}
  .hero-badge svg{width:14px;height:14px}
}
@media(prefers-reduced-motion:reduce){
  .hero-list li,.hero-list li::before{transition:none}
}

/* marquee */
.marquee{border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:20px 0;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.mq-track{display:flex;gap:52px;width:max-content;animation:mq 28s linear infinite}
.marquee:hover .mq-track{animation-play-state:paused}
@keyframes mq{to{transform:translateX(-50%)}}
.mq-track span{font-family:var(--serif);font-weight:600;font-size:1.15rem;color:var(--muted);display:inline-flex;align-items:center;gap:52px;white-space:nowrap}
.mq-track span::after{content:"✦";color:var(--accent);font-size:.8rem}

/* trusted-by logo wall: no cards. The logos are pre-flattened to white ink on
   transparency (scripts/make-trust-mono.php), so the strip sits straight on the
   page background and light mode just inverts the ink to black. */
.trust{padding:56px 0 12px}
.trust-ey{text-align:center;font-family:var(--serif);color:var(--faint);font-size:.82rem;letter-spacing:.04em;margin:0 0 30px}
.trust-grid{display:flex;flex-wrap:wrap;justify-content:center;gap:14px 30px;align-items:center}
/* max-width caps the tile so the wall never scales up into eight big stamps: at
   the 4-up tablet width a pure flex-basis gave 215px-wide / 87px-tall logos, four
   times the 47px they run at on a desktop. */
.trust-logo{flex:0 1 calc((100% - 7*30px)/8);max-width:150px;opacity:.6;
  transition:opacity .35s,transform .35s cubic-bezier(.2,.7,.2,1)}
.trust-logo img{display:block;width:100%;height:auto}
.trust-logo:hover{opacity:1;transform:translateY(-3px)}
:root[data-theme="light"] .trust-logo{opacity:.55}
:root[data-theme="light"] .trust-logo img{filter:invert(1)}
@media(max-width:1040px){.trust-grid{gap:18px 34px}.trust-logo{flex-basis:calc((100% - 3*34px)/4)}}
/* Phones keep the 4-up grid (two tidy rows of four) rather than dropping to 2-up:
   at two per row the logos blew up to ~140px wide and the strip read as eight big
   stamps instead of a quiet wall. Narrower gap, and the tile is capped so the wall
   never grows past a comfortable ~34px cap height. */
@media(max-width:640px){.trust{padding:34px 0 6px}.trust-grid{gap:16px 18px}
  .trust-logo{flex-basis:calc((100% - 3*18px)/4)}
  .trust-ey{margin-bottom:18px;font-size:.76rem}}

/* cookie consent */
/* Cookie notice — full-bleed dark bar across the bottom, the reference's shape.
   Notice-only: one dismiss button, no decline, no settings link (see tvConsent
   in app.js for why a stored 'denied' is still honoured). Uses the About page's
   --panel token pair so it is a dark bar in BOTH themes rather than vanishing
   into the dark one. */
.tv-cookie{position:fixed;left:0;right:0;bottom:0;z-index:120;width:100%;
  display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;
  gap:14px clamp(18px,3vw,44px);padding:15px clamp(18px,2.6vw,44px);
  background:var(--panel);border-top:1px solid var(--panel-line);
  box-shadow:0 -16px 44px rgba(0,0,0,.3);
  opacity:0;transform:translateY(100%);transition:opacity .35s,transform .35s}
.tv-cookie.in{opacity:1;transform:none}
.tv-cookie-t{margin:0;flex:1 1 340px;font-size:.86rem;line-height:1.55;color:var(--panel-mute)}
.tv-cookie-t a{color:var(--panel-ink);text-decoration:underline;text-underline-offset:2px}
.tv-cookie-b{display:flex;flex:0 0 auto}
.tv-ck-accept{font-family:var(--sans);font-size:.82rem;font-weight:600;cursor:pointer;
  padding:10px 26px;border-radius:8px;border:1px solid var(--accent);
  background:var(--accent);color:#fff;transition:all .2s}
.tv-ck-accept:hover{background:var(--accent-soft);border-color:var(--accent-soft)}
@media(max-width:560px){
  .tv-cookie{padding:14px 18px 16px}
  .tv-cookie-t{flex:1 1 100%;font-size:.8rem}
  .tv-cookie-b{flex:1 1 100%}
  .tv-ck-accept{width:100%;padding:12px 26px}
}

/* 404 page */
.e404{min-height:calc(100vh - 200px);display:grid;place-items:center;text-align:center;padding:120px 0 80px;position:relative}
.e404-in{position:relative;max-width:640px}
.e404-big{font-family:var(--serif);font-weight:800;font-size:clamp(6rem,26vw,15rem);line-height:.9;letter-spacing:-.04em;
  background:linear-gradient(120deg,var(--accent),var(--gold));-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;opacity:.16;margin:0 0 -10px;user-select:none;pointer-events:none}
.e404 .sec-num{display:block;margin:0 0 12px}
.e404 h1{font-size:var(--fs-h);line-height:var(--lh-h);margin:0 0 14px}
.e404 p{color:var(--muted);font-size:1.05rem;max-width:44ch;margin:0 auto 30px}
.e404-btns{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin:0 0 40px}
.e404-links{display:flex;gap:8px 22px;justify-content:center;flex-wrap:wrap;padding-top:26px;border-top:1px solid var(--line)}
.e404-links a{font-family:var(--sans);font-size:.86rem;color:var(--muted);transition:color .2s}
.e404-links a:hover{color:var(--accent)}

/* journal article (post.html) */
.post{padding:120px 0 40px}
.post-in{max-width:760px}
.post-back{display:inline-flex;align-items:center;gap:8px;font-family:var(--sans);font-size:.82rem;font-weight:600;
  color:var(--muted);margin:0 0 34px;transition:color .2s}
.post-back svg{width:16px;height:16px}
.post-back:hover{color:var(--accent)}
.post-cat{display:inline-block;font-family:var(--sans);font-weight:600;font-size:.72rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent);margin:0 0 16px}
.post-head h1{font-size:var(--fs-h);line-height:var(--lh-h);margin:0 0 16px}
.post-meta{font-family:var(--serif);color:var(--faint);font-size:.9rem;margin:0 0 36px;
  padding-bottom:30px;border-bottom:1px solid var(--line)}
.post-body{font-size:1.08rem;line-height:1.75;color:var(--ink)}
.post-body>*{margin:0 0 22px}
.post-body h2{font-size:1.6rem;line-height:1.15;margin:44px 0 16px}
.post-body h3{font-size:1.25rem;line-height:1.2;margin:36px 0 12px}
.post-body p{color:var(--muted)}
.post-body a{color:var(--accent);text-decoration:underline;text-underline-offset:3px}
.post-body ul,.post-body ol{padding-left:22px;color:var(--muted)}
.post-body li{margin:0 0 10px}
.post-body img{max-width:100%;height:auto;border-radius:10px;border:1px solid var(--line)}
.post-body blockquote{border-left:3px solid var(--accent);padding:4px 0 4px 22px;margin:28px 0;
  font-family:var(--serif);font-size:1.3rem;line-height:1.4;color:var(--ink)}
.post-body strong,.post-body b{color:var(--ink);font-weight:600}
.post-nav{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:52px 0 0;
  border-top:1px solid var(--line);padding-top:32px}
.post-nav a{display:flex;flex-direction:column;gap:6px;padding:16px 18px;border:1px solid var(--line);
  border-radius:10px;background:var(--bg2);transition:border-color .25s,transform .25s}
.post-nav a:hover{border-color:color-mix(in srgb,var(--accent) 45%,var(--line));transform:translateY(-2px)}
.post-nav .pn-next{text-align:right}
.post-nav a span{font-family:var(--sans);font-size:.74rem;letter-spacing:.06em;color:var(--faint);text-transform:uppercase}
.post-nav a b{font-family:var(--serif);font-weight:600;font-size:.98rem;color:var(--ink);line-height:1.25}
.post-cta{text-align:center;background:var(--bg2);border:1px solid var(--line);border-radius:12px;
  padding:40px 28px;margin:56px 0 0}
.post-cta h3{font-size:1.5rem;margin:0 0 8px}
.post-cta p{color:var(--muted);margin:0 0 22px}
@media(max-width:560px){.post{padding:96px 0 30px}.post-nav{grid-template-columns:1fr}.post-nav .pn-next{text-align:left}}

/* pricing — service price list */
.price-list{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-top:6px}
.price-row{display:flex;align-items:center;justify-content:space-between;gap:18px;
  padding:20px 22px;border:1px solid var(--line);border-radius:12px;background:var(--bg2);
  transition:border-color .25s,transform .25s}
.price-row:hover{border-color:color-mix(in srgb,var(--accent) 40%,var(--line));transform:translateY(-2px)}
.pr-info h3{font-family:var(--serif);font-weight:600;font-size:1.06rem;margin:0 0 4px}
.pr-info p{margin:0;color:var(--muted);font-size:.87rem;line-height:1.45}
.pr-cost{flex:none;font-family:var(--serif);font-weight:700;font-size:1.04rem;color:var(--accent);text-align:right}
.price-note{text-align:center;color:var(--muted);font-size:.92rem;margin-top:24px}
.price-note a{color:var(--accent)}
@media(max-width:720px){.price-list{grid-template-columns:1fr}}
@media(max-width:420px){.price-row{padding:16px 18px;gap:12px}.pr-cost{font-size:.96rem}}

/* floating whatsapp button */
.tv-wa{position:fixed;right:20px;bottom:20px;z-index:110;display:inline-flex;align-items:center;gap:0;
  height:46px;padding:0;border-radius:100px;background:#25d366;color:#fff;overflow:hidden;
  box-shadow:0 6px 16px rgba(0,0,0,.28);transition:box-shadow .25s,transform .25s,gap .3s,padding .3s}
/* the glyph's flex-basis, width and height must move together — set only one and
   the SVG gets crushed into a sliver (that bug shipped once already) */
.tv-wa svg{flex:0 0 46px;width:46px;height:46px;padding:12px;box-sizing:border-box;display:block}
.tv-wa-lbl{font-family:var(--sans);font-weight:600;font-size:.9rem;white-space:nowrap;max-width:0;opacity:0;
  transition:max-width .3s,opacity .25s,padding-right .3s;padding-right:0}
.tv-wa:hover{transform:translateY(-2px);box-shadow:0 10px 22px rgba(0,0,0,.34)}
.tv-wa:hover .tv-wa-lbl{max-width:160px;opacity:1;padding-right:20px}
@media(max-width:520px){.tv-wa{right:14px;bottom:14px;height:42px}.tv-wa svg{flex-basis:42px;width:42px;height:42px;padding:11px}
  .tv-wa-lbl{display:none}}
@media(prefers-reduced-motion:reduce){.tv-wa,.tv-wa-lbl{transition:none}}

/* work grid */
/* Microsoft-style sticky pill tab-bar */
.filters-wrap{position:sticky;top:84px;z-index:30;display:flex;justify-content:center;margin:0 0 40px;pointer-events:none}
/* ---- LIQUID GLASS ---- shared flowing-highlight animation for glassy surfaces */
@keyframes glassFlow{0%,100%{background-position:0% 0%,100% 100%}50%{background-position:26% 10%,74% 90%}}
@media(prefers-reduced-motion:reduce){.filters::before,.nav-links.main::before{animation:none}}

.filters{position:relative;isolation:isolate;display:inline-flex;flex-wrap:nowrap;gap:2px;max-width:100%;overflow-x:auto;scrollbar-width:none;
  padding:7px;border:1px solid rgba(255,255,255,.16);border-radius:10px;
  background:linear-gradient(135deg,rgba(255,255,255,.14),rgba(255,255,255,.02) 42%,rgba(255,255,255,.08));
  box-shadow:0 18px 46px -16px rgba(0,0,0,.62),0 2px 8px -5px rgba(0,0,0,.5),
    inset 0 1px 1px rgba(255,255,255,.55),inset 0 -10px 24px -16px rgba(255,255,255,.3),inset 0 0 0 1px rgba(255,255,255,.05);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);pointer-events:auto}
.filters::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;border-radius:inherit;
  background:radial-gradient(120% 92% at 18% -12%,rgba(255,255,255,.42),transparent 55%),radial-gradient(90% 74% at 86% 122%,rgba(255,255,255,.16),transparent 55%);
  /* PERF: static now — the infinite glassFlow loop re-blurred the bar's backdrop every frame */}
.filters .filter{z-index:1}
:root[data-theme="light"] .filters{border-color:rgba(0,0,0,.08);
  background:linear-gradient(135deg,rgba(255,255,255,.62),rgba(255,255,255,.42) 42%,rgba(255,255,255,.55));
  box-shadow:0 18px 46px -16px rgba(0,0,0,.22),0 2px 8px -5px rgba(0,0,0,.14),
    inset 0 1px 1px rgba(255,255,255,.85),inset 0 -10px 24px -16px rgba(0,0,0,.05),inset 0 0 0 1px rgba(255,255,255,.4)}
:root[data-theme="light"] .filters::before{background:radial-gradient(120% 92% at 18% -12%,rgba(255,255,255,.7),transparent 55%),radial-gradient(90% 74% at 86% 122%,rgba(255,255,255,.3),transparent 55%)}
.filters::-webkit-scrollbar{display:none}
.filter{position:relative;font-family:var(--sans);font-weight:600;font-size:.86rem;color:var(--muted);background:none;
  border:none;padding:10px 18px;border-radius:8px;white-space:nowrap;cursor:pointer;transition:color .2s,background .2s}
.filter:hover{color:var(--ink);background:rgba(255,255,255,.08)}
:root[data-theme="light"] .filter:hover{background:rgba(0,0,0,.05)}
.filter.active{color:var(--ink)}
.filter.active::after{content:"";position:absolute;left:18px;right:18px;bottom:4px;height:2.5px;background:var(--accent);border-radius:3px}
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
@media(max-width:900px){.grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.grid{grid-template-columns:1fr}}
/* mobile-only: sticky stacking work cards (like the Software page) */
@media(max-width:560px){
  .filters{-webkit-backdrop-filter:none;backdrop-filter:none;background:rgba(17,17,19,.94)}
  :root[data-theme="light"] .filters{background:rgba(255,253,249,.96)}
  .grid{display:block}
  .grid>.card{position:sticky;top:calc(80px + var(--i,0)*14px);margin-bottom:20px;
    box-shadow:0 10px 18px rgba(0,0,0,.42)}
  .grid>.card:last-child{margin-bottom:0}
  .grid>.card:hover{transform:none}
  .grid>.card .card-meta p{opacity:1;max-height:80px}
  /* tap-to-open: when the deck is long ("All"), collapse it to a single peek so it
     isn't overwhelming and there's nothing tall to scroll back through until the
     visitor opts in. overflow:hidden also disables the sticky stack while closed. */
  .grid.collapsible:not(.open){max-height:82vh;overflow:hidden;
    -webkit-mask-image:linear-gradient(180deg,#000 64%,transparent);
            mask-image:linear-gradient(180deg,#000 64%,transparent)}
  .grid.collapsible:not(.open)>.card{position:relative;top:auto;margin-bottom:16px}
  /* tap-to-open control lives on mobile only; JS toggles [hidden] per view.
     grid-adjacency keeps this ahead of the desktop base rule below, whatever
     the source order. */
  .grid+.work-toggle{display:flex}
  .grid+.work-toggle[hidden]{display:none}
}
/* control is desktop-hidden by default so it can never leak onto the wide grid,
   even if the viewport crosses the breakpoint without JS re-running */
.work-toggle{display:none;align-items:center;justify-content:center;gap:8px;
  width:100%;margin-top:18px;padding:15px 20px;cursor:pointer;
  font-family:var(--sans);font-weight:600;font-size:.95rem;color:var(--ink);
  background:linear-gradient(135deg,rgba(255,255,255,.14),rgba(255,255,255,.03));
  border:1px solid rgba(255,255,255,.16);border-radius:10px;
  box-shadow:0 10px 26px -12px rgba(0,0,0,.55);transition:transform .12s,border-color .2s}
.work-toggle:active{transform:scale(.98)}
.work-toggle:hover{border-color:rgba(255,77,28,.5)}
.work-toggle svg{width:18px;height:18px}
:root[data-theme="light"] .work-toggle{color:var(--ink);
  background:linear-gradient(135deg,rgba(255,255,255,.72),rgba(255,255,255,.5));
  border-color:rgba(0,0,0,.08)}
/* touch devices have no hover, so always show the one-line descriptor */
@media(hover:none){.card .card-meta p{opacity:1;max-height:80px}}
.card{display:block;text-decoration:none;color:inherit;position:relative;border-radius:var(--r);overflow:hidden;border:1px solid var(--line);background:var(--bg2);
  cursor:pointer;transition:transform .4s cubic-bezier(.2,.7,.2,1),border-color .3s;transform:translateY(0)}
.card:hover{transform:translateY(-6px);border-color:rgba(255,77,28,.5)}
.card-img{position:relative;aspect-ratio:4/5;overflow:hidden;background:var(--bg3)}
.card-img img,.card-img video{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .7s cubic-bezier(.2,.7,.2,1)}
.card:hover .card-img img,.card:hover .card-img video{transform:scale(1.06)}
.card-img .card-illo{width:100%;height:100%;display:block;transition:transform .7s cubic-bezier(.2,.7,.2,1)}
.card:hover .card-img .card-illo{transform:scale(1.06)}
.lb-img .card-illo{width:100%;height:100%;min-height:360px;display:block}
@media(max-width:760px){.lb-img .card-illo{min-height:0;aspect-ratio:16/11;height:auto}}
.card-img::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 45%,rgba(0,0,0,.82));opacity:.9;transition:.4s}
.card-cat{position:absolute;top:12px;left:12px;z-index:2;font-size:.68rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  padding:5px 11px;border-radius:6px;background:rgba(0,0,0,.74);color:#fff;border:1px solid rgba(255,255,255,.14)}
.card-meta{position:absolute;bottom:0;left:0;right:0;z-index:2;padding:18px}
.card-meta .num{font-family:var(--serif);color:var(--accent);font-size:.72rem;font-weight:700}
.card-meta h3{color:#fff;font-size:1.18rem;margin:5px 0 4px}
.card-meta p{color:#c7c2b9;font-size:.83rem;font-weight:300;opacity:0;max-height:0;transition:.4s;line-height:1.45}
.card:hover .card-meta p{opacity:1;max-height:70px}
.card-arrow{position:absolute;top:12px;right:12px;z-index:2;width:34px;height:34px;border-radius:50%;background:var(--accent);color:#fff;
  display:grid;place-items:center;opacity:0;transform:scale(.6);transition:.35s}
.card:hover .card-arrow{opacity:1;transform:scale(1)} .card-arrow svg{width:16px;height:16px}
/* real-work cards render as buttons — strip native button chrome */
/* work tiles are display only — no preview, so nothing may imply a tap target */
.card.work{font:inherit;color:inherit;text-align:left;width:100%;padding:0;cursor:default}
.card.work:hover{transform:none;border-color:var(--line)}
.card.work:hover .card-img img,.card.work:hover .card-img video{transform:none}
.work-foot{text-align:center;margin-top:44px}

/* services */
.svc-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:20px}
@media(max-width:760px){.svc-grid{grid-template-columns:1fr}}
.svc{padding:32px;border:1px solid var(--line);border-radius:var(--r);background:var(--bg2);transition:.35s;position:relative;overflow:hidden}
.svc:hover{border-color:rgba(255,77,28,.45);transform:translateY(-4px)}
.svc::before{content:"";position:absolute;top:0;left:0;width:100%;height:3px;background:linear-gradient(90deg,var(--accent),var(--gold));transform:scaleX(0);transform-origin:left;transition:.4s}
.svc:hover::before{transform:scaleX(1)}
.svc-ic{width:50px;height:50px;border-radius:10px;background:var(--bg3);border:1px solid var(--line);display:grid;place-items:center;color:var(--accent);margin-bottom:20px}
.svc-ic svg{width:24px;height:24px}
.svc h3{font-size:1.32rem;margin-bottom:10px}
.svc p{color:var(--muted);font-size:.95rem;margin-bottom:16px}
.svc ul{list-style:none;display:flex;flex-wrap:wrap;gap:7px}
.svc li{font-size:.76rem;color:var(--ink);background:var(--bg3);border:1px solid var(--line);padding:5px 11px;border-radius:6px}

/* packages */
.pkg-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
@media(max-width:860px){.pkg-grid{grid-template-columns:1fr;max-width:460px;margin:0 auto}}
.pkg{padding:34px 30px;border:1px solid var(--line);border-radius:var(--r);background:var(--bg2);display:flex;flex-direction:column;transition:.35s}
.pkg:hover{transform:translateY(-4px);border-color:var(--line)}
.pkg.feat{border-color:var(--accent);background:linear-gradient(180deg,rgba(255,77,28,.08),transparent 40%)}
.pkg .tier{font-family:var(--serif);font-weight:700;font-size:1.35rem}
.pkg .flag{align-self:flex-start;font-size:.68rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:#fff;
  background:var(--accent);padding:4px 11px;border-radius:6px;margin-bottom:14px}
.pkg .price{font-family:var(--serif);font-weight:800;font-size:2.1rem;margin:10px 0 4px}
.pkg .price small{font-family:var(--sans);font-weight:400;font-size:.8rem;color:var(--muted)}
.pkg .for{color:var(--muted);font-size:.9rem;margin-bottom:20px}
.pkg ul{list-style:none;display:flex;flex-direction:column;gap:11px;margin-bottom:26px;flex:1}
.pkg li{display:flex;gap:10px;align-items:flex-start;font-size:.9rem;color:var(--ink)}
.pkg li svg{width:17px;height:17px;color:var(--accent);flex-shrink:0;margin-top:3px}
.pkg .btn{justify-content:center;width:100%}

/* faq */
.faq{max-width:760px;margin:0 auto}
.qa{border-bottom:1px solid var(--line)}
.qa summary{list-style:none;cursor:pointer;padding:22px 0;display:flex;justify-content:space-between;gap:20px;align-items:center;
  font-family:var(--serif);font-weight:600;font-size:1.12rem}
.qa summary::-webkit-details-marker{display:none}
.qa summary .pm{width:26px;height:26px;flex-shrink:0;border:1px solid var(--line);border-radius:50%;display:grid;place-items:center;color:var(--accent);transition:.3s}
.qa[open] summary .pm{transform:rotate(45deg)}
.qa p{color:var(--muted);padding:0 0 22px;font-size:.98rem;max-width:64ch}
/* JS-wrapped answer body — collapse is driven by [open] so it hides correctly even
   though the content is no longer a direct <details> child; height is transitioned. */
.qa-body{overflow:hidden;height:0}
.qa[open] .qa-body{height:auto}
.qa-body.is-anim{transition:height .34s cubic-bezier(.2,.7,.2,1)}

/* about page */
.about-grid{display:grid;grid-template-columns:.9fr 1.1fr;gap:52px;align-items:center}
@media(max-width:860px){.about-grid{grid-template-columns:1fr;gap:36px}}
.about-photo{position:relative;border-radius:16px;overflow:hidden;border:1px solid var(--line);aspect-ratio:1/1}
.about-photo img{width:100%;height:100%;object-fit:cover}
.about-body h2{font-size:var(--fs-h);line-height:var(--lh-h);margin:16px 0 20px}
.quote{font-family:var(--serif);font-weight:600;font-size:1.35rem;line-height:1.35;margin:0 0 24px;padding-left:20px;border-left:3px solid var(--accent)}
.about-body p{color:var(--muted);margin-bottom:16px;font-size:1rem}
.about-tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:24px}
.about-tags span{font-size:.8rem;color:var(--ink);background:var(--bg2);border:1px solid var(--line);padding:7px 14px;border-radius:6px}
.timeline{max-width:760px;margin:0 auto;position:relative}
.tl{display:grid;grid-template-columns:120px 1fr;gap:26px;padding:26px 0;border-bottom:1px solid var(--line)}
@media(max-width:560px){.tl{grid-template-columns:1fr;gap:8px}}
.tl .yr{font-family:var(--serif);font-weight:700;color:var(--accent);font-size:1.1rem}
.tl h3{font-size:1.2rem;margin-bottom:6px}
.tl p{color:var(--muted);font-size:.94rem}
.val-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
@media(max-width:760px){.val-grid{grid-template-columns:1fr}}
.val{padding:28px;border:1px solid var(--line);border-radius:var(--r);background:var(--bg2)}
.val .vic{width:44px;height:44px;border-radius:10px;background:var(--bg3);border:1px solid var(--line);display:grid;place-items:center;color:var(--accent);margin-bottom:16px}
.val .vic svg{width:22px;height:22px}
.val h3{font-size:1.18rem;margin-bottom:8px} .val p{color:var(--muted);font-size:.92rem}

/* process */
.proc-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:20px}
@media(max-width:860px){.proc-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:460px){.proc-grid{grid-template-columns:1fr}}
.proc{padding:26px;border:1px solid var(--line);border-radius:var(--r);background:var(--bg2)}
.proc .pn{font-family:var(--serif);font-weight:800;font-size:2.4rem;color:transparent;-webkit-text-stroke:1.4px var(--accent);margin-bottom:14px}
.proc h3{font-size:1.12rem;margin-bottom:8px} .proc p{color:var(--muted);font-size:.9rem}

/* stats band */
.band{border-top:1px solid var(--line);border-bottom:1px solid var(--line);background:var(--bg2)}
.band-grid{display:grid;grid-template-columns:repeat(4,1fr)}
@media(max-width:640px){.band-grid{grid-template-columns:repeat(2,1fr)}}
.band-cell{padding:44px 20px;text-align:center;border-right:1px solid var(--line)}
.band-cell:last-child{border-right:none}
@media(max-width:640px){.band-cell:nth-child(2){border-right:none}.band-cell:nth-child(1),.band-cell:nth-child(2){border-bottom:1px solid var(--line)}}
.band-cell .n{font-family:var(--serif);font-weight:800;font-size:clamp(2.2rem,5vw,3.2rem);line-height:1}
.band-cell .n span{color:var(--accent)}
.band-cell .l{color:var(--muted);font-size:.84rem;margin-top:10px;letter-spacing:.03em}

/* CTA */
.cta{text-align:center;padding:72px 0}
.cta h2{font-size:var(--fs-h);line-height:var(--lh-h);margin:18px 0 22px;overflow-wrap:break-word}
.cta h2 .em{background:linear-gradient(120deg,var(--accent),var(--gold));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.cta p{color:var(--muted);font-size:var(--fs-sub);line-height:var(--lh-sub);max-width:44ch;margin:0 auto 36px}
.cta-btns{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}
.chan{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;margin-top:48px}
.chan a{display:flex;align-items:center;gap:10px;padding:12px 20px;border:1px solid var(--line);border-radius:10px;background:var(--bg2);font-size:.9rem;font-weight:500;transition:.28s}
.chan a:hover{border-color:var(--accent);transform:translateY(-3px);color:var(--accent)}
.chan svg{width:18px;height:18px}

/* contact page */
.contact-grid{display:grid;grid-template-columns:1.1fr .9fr;gap:44px;align-items:start}
@media(max-width:860px){.contact-grid{grid-template-columns:1fr;gap:34px}}
.form{border:1px solid var(--line);border-radius:var(--r);background:var(--bg2);padding:34px}
.field{margin-bottom:18px}
.field label{display:block;font-size:.82rem;font-weight:500;color:var(--muted);margin-bottom:8px}
.field input,.field textarea,.field select{width:100%;background:var(--bg);border:1px solid var(--line);border-radius:10px;
  padding:13px 15px;color:var(--ink);font-family:var(--sans);font-size:.95rem;font-weight:300;transition:.25s}
.field input:focus,.field textarea:focus,.field select:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(255,77,28,.15)}
.field textarea{resize:vertical;min-height:120px}
.chip-row{display:flex;flex-wrap:wrap;gap:8px}
/* real <button> elements, so they are tabbable and announce their pressed state -
   the UA font and appearance have to be reset for them to look unchanged */
.chip{font-family:inherit;font-size:.83rem;line-height:1.4;color:var(--muted);background:var(--bg);
  border:1px solid var(--line);padding:9px 15px;border-radius:8px;cursor:pointer;transition:.22s;
  user-select:none;-webkit-appearance:none;appearance:none}
.chip:hover{color:var(--ink)}
.field-label{display:block;font-size:.8rem;font-weight:600;color:var(--muted);margin-bottom:8px}
.chip.on{background:var(--accent);color:#fff;border-color:var(--accent)}
.form .btn{width:100%;justify-content:center;margin-top:6px}
.form-note{font-size:.78rem;color:var(--faint);text-align:center;margin-top:14px}
.form-err{margin-bottom:16px;padding:11px 14px;border-radius:8px;font-size:.86rem;
  color:#ffb4a0;background:rgba(255,77,28,.12);border:1px solid rgba(255,77,28,.4)}
:root[data-theme="light"] .form-err{color:#a1330f;background:rgba(255,77,28,.09)}
.info-card{border:1px solid var(--line);border-radius:var(--r);background:var(--bg2);padding:28px;margin-bottom:16px}
.info-card h3{font-size:1.1rem;margin-bottom:16px}
.info-row{display:flex;gap:14px;align-items:center;padding:12px 0;border-bottom:1px solid var(--line2)}
.info-row:last-child{border-bottom:none}
/* Page text is deliberately unselectable site-wide, which also means a visitor
   cannot highlight the phone number or email to copy them. These buttons are the
   sanctioned way out: one tap puts the value on the clipboard, nothing else. */
.info-line{display:flex;align-items:center;gap:8px;border-bottom:1px solid var(--line2)}
.info-line:last-child{border-bottom:none}
.info-line .info-row{flex:1;min-width:0;border-bottom:none}
.copy-btn{flex-shrink:0;width:38px;height:38px;display:grid;place-items:center;cursor:pointer;
  border:1px solid var(--line);border-radius:8px;background:var(--bg3);color:var(--muted);
  transition:.22s;-webkit-appearance:none;appearance:none}
.copy-btn:hover{color:var(--ink);border-color:var(--accent)}
.copy-btn svg{width:16px;height:16px}
.copy-btn .ic-done{display:none;color:var(--accent)}
.copy-btn.done{border-color:var(--accent);color:var(--accent)}
.copy-btn.done .ic-copy{display:none}
.copy-btn.done .ic-done{display:block}
.info-row .ric{width:40px;height:40px;border-radius:10px;background:var(--bg3);border:1px solid var(--line);display:grid;place-items:center;color:var(--accent);flex-shrink:0}
.info-row .ric svg{width:19px;height:19px}
/* stack label over value so they don't run together, e.g. "Emailteniola484@…" */
.info-row>span:not(.ric){display:flex;flex-direction:column;gap:3px;min-width:0}
.info-row .rl{font-size:.72rem;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}
/* value reuses the reveal class name (.rv) — pin it visible so it reveals with
   its card instead of animating in separately after the label */
.info-row .rv{font-size:.98rem;font-weight:600;line-height:1.35;overflow-wrap:anywhere;opacity:1;transform:none}
.book-card{background:linear-gradient(180deg,rgba(255,77,28,.09),transparent 55%),var(--bg2);border-color:rgba(255,77,28,.35)}
.book-card h3{margin-bottom:8px}
.book-copy{color:var(--muted);font-size:.92rem;margin-bottom:18px}
.book-btn{width:100%;justify-content:center}

/* lightbox */
.lb{position:fixed;inset:0;z-index:100;background:rgba(6,6,7,.88);backdrop-filter:blur(8px);display:none;align-items:center;justify-content:center;padding:24px;opacity:0;transition:opacity .3s}
.lb.open{display:flex;opacity:1}
.lb-card{background:linear-gradient(160deg,rgba(24,24,30,.9),rgba(15,15,19,.84));border:1px solid rgba(255,255,255,.12);
  box-shadow:inset 0 1px 1px rgba(255,255,255,.28),inset 0 -20px 40px -30px rgba(255,255,255,.18),0 40px 90px -30px rgba(0,0,0,.7);
  -webkit-backdrop-filter:blur(24px) saturate(180%);backdrop-filter:blur(24px) saturate(180%);
  border-radius:16px;max-width:940px;width:100%;max-height:90vh;overflow:hidden;display:grid;grid-template-columns:1.15fr .85fr;transform:scale(.96);transition:.35s}
:root[data-theme="light"] .lb-card{background:linear-gradient(160deg,rgba(255,255,255,.92),rgba(250,248,244,.86));border-color:rgba(0,0,0,.08);
  box-shadow:inset 0 1px 1px rgba(255,255,255,.9),inset 0 -20px 40px -30px rgba(0,0,0,.05),0 40px 90px -30px rgba(0,0,0,.35)}
.lb.open .lb-card{transform:scale(1)}
@media(max-width:760px){.lb-card{grid-template-columns:1fr;max-height:92vh;overflow-y:auto}}
.lb-img{background:var(--bg3);display:grid;place-items:center;overflow:hidden}
.lb-img img{width:100%;height:100%;max-height:90vh;object-fit:cover}
@media(max-width:760px){.lb-img img{max-height:44vh}}
.lb-body{padding:34px;display:flex;flex-direction:column;justify-content:center}
.lb-body .num{font-family:var(--serif);color:var(--accent);font-weight:700;font-size:.8rem}
.lb-body h3{font-size:1.7rem;margin:8px 0 4px} .lb-body .yr{color:var(--muted);font-size:.86rem;margin-bottom:18px}
.lb-body p{color:var(--muted);font-size:.95rem;margin-bottom:20px}
.lb-tags{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:26px}
.lb-tags span{font-size:.74rem;background:var(--bg3);border:1px solid var(--line);padding:5px 11px;border-radius:6px}
.lb-close{position:absolute;top:20px;right:20px;z-index:110;width:44px;height:44px;border-radius:50%;background:var(--bg2);border:1px solid var(--line);color:var(--ink);display:grid;place-items:center;cursor:pointer;transition:.25s}
.lb-close:hover{background:var(--accent);color:#fff;border-color:var(--accent);transform:rotate(90deg)}

/* footer */
footer{border-top:1px solid var(--line);padding:56px 0 40px}
.foot-top{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:32px;margin-bottom:40px}
@media(max-width:760px){.foot-top{grid-template-columns:1fr;gap:26px}}
.foot-brand .brand{margin-bottom:14px}
.foot-brand p{color:var(--muted);font-size:.9rem;max-width:34ch}
.foot-col h4{font-family:var(--sans);font-size:.74rem;letter-spacing:.14em;text-transform:uppercase;color:var(--faint);margin-bottom:14px}
.foot-col a{display:block;color:var(--muted);font-size:.92rem;padding:5px 0;transition:.2s}
.foot-col a:hover{color:var(--accent)}
.foot-bot{display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap;padding-top:24px;border-top:1px solid var(--line)}
.foot-bot p{color:var(--faint);font-size:.82rem}
/* footer Â· areas served */
.foot-areas{padding-top:22px;border-top:1px solid var(--line);margin-bottom:4px}
.foot-areas h4{font-family:var(--sans);font-size:.74rem;letter-spacing:.14em;text-transform:uppercase;color:var(--faint);margin-bottom:12px}
.foot-areas p{color:var(--faint);font-size:.75rem;line-height:1.85;max-width:none;margin:0}
/* WhatsApp QR · shown on desktop only (a phone can't scan its own screen) */
.wa-qr{display:none}
@media(min-width:900px){
  .wa-qr{display:flex;align-items:center;gap:16px;margin-top:18px;padding-top:18px;border-top:1px solid var(--line)}
  .wa-qr img{width:112px;height:auto;border-radius:10px;flex:none;box-shadow:0 8px 20px rgba(20,15,10,.16)}
  .wa-qr-cap b{display:block;font-family:var(--sans);font-weight:700;font-size:.98rem;color:var(--ink);margin-bottom:5px}
  .wa-qr-cap span{color:var(--muted);font-size:.84rem;line-height:1.45}
  .wa-qr.center{justify-content:center;max-width:440px;margin-left:auto;margin-right:auto;text-align:left}
}
.foot-social{display:flex;gap:10px}
.foot-social a{width:38px;height:38px;border-radius:50%;border:1px solid var(--line);display:grid;place-items:center;color:var(--muted);transition:.25s}
.foot-social a:hover{color:var(--accent);border-color:var(--accent);transform:translateY(-2px)}
.foot-social svg{width:17px;height:17px}

/* ===== APPLE-STYLE MEGA FOOTER DIRECTORY ===== */
.megafoot{border-top:1px solid var(--line);background:var(--bg2);padding:60px 0 44px}
.mf-dir{display:grid;grid-template-columns:repeat(5,1fr);gap:36px 28px;margin-bottom:52px}
.mf-col h4{font-family:var(--serif);font-weight:700;font-size:.9rem;letter-spacing:-.01em;color:var(--ink);margin:0 0 14px}
.mf-col h4:not(:first-child){margin-top:26px}
.mf-col a{display:block;color:var(--muted);font-size:.86rem;line-height:1.5;padding:5px 0;transition:color .18s,transform .18s;width:fit-content}
.mf-col a:hover{color:var(--accent);transform:translateX(2px)}
.mf-col a.ext::after{content:"↗";font-size:.72em;opacity:.5;margin-left:4px}
/* tablet/mobile: switch the rigid grid to a tight-packing multi-column flow so
   short columns don't leave big empty gaps next to taller ones */
@media(max-width:900px){
  .mf-dir{display:block;column-count:3;column-gap:28px}
  .mf-col{break-inside:avoid;-webkit-column-break-inside:avoid;margin-bottom:30px}
}
@media(max-width:560px){.mf-dir{column-count:2;column-gap:24px}}
/* newsletter strip inside mega footer */
/* Footer newsletter. It is the biggest ask in the footer, so it is a DARK PANEL
   rather than a grey slab — the same punctuation device as the About stats band
   and the value cards, which makes it a deliberate block on the white theme and
   a warm raised one on the black. Because the panel is dark in BOTH themes, the
   input's colours are fixed light-on-dark rather than theme tokens.
   Two dead rules went with the old version: `.mf-note{grid-column:1/-1}` did
   nothing (its parent is a flex form, not the grid) and the -6px margin beside
   it pulled the note up into the button. The form is now a block wrapping an
   `.mf-row`, so the note sits under the field properly. */
.mf-news{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(24px,4vw,52px);align-items:center;
  padding:clamp(26px,3.4vw,44px);border:1px solid var(--panel-line);border-radius:16px;
  background:var(--panel);color:var(--panel-ink);margin-bottom:48px}
.mf-ey{display:block;font-family:var(--sans);font-weight:600;font-size:.7rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--panel-mute);margin-bottom:12px}
.mf-news h3{font-size:clamp(1.35rem,2.2vw,1.8rem);line-height:1.08;letter-spacing:-.02em;
  margin:0 0 10px;color:var(--panel-ink)}
/* scoped to .mf-copy, NOT .mf-news: `.mf-news p` also matched .mf-note and,
   being more specific, zeroed the margin that separates it from the field */
.mf-copy p{color:var(--panel-mute);font-size:.95rem;line-height:1.6;max-width:44ch;margin:0}
.mf-news .em{color:var(--accent)}
.mf-form{display:block}
.mf-row{display:flex;gap:10px;flex-wrap:wrap}
.mf-form input{flex:1 1 200px;min-width:0;padding:14px 16px;border-radius:8px;
  border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.07);color:var(--panel-ink);
  font-family:var(--sans);font-size:.92rem;transition:border-color .2s,background .2s}
.mf-form input::placeholder{color:rgba(244,241,236,.45)}
.mf-form input:focus{outline:none;border-color:var(--accent);background:rgba(255,255,255,.12)}
.mf-form button{white-space:nowrap;flex:0 0 auto}
.mf-note{color:var(--panel-mute);font-size:.78rem;line-height:1.5;margin:12px 0 0;opacity:.85}
@media(max-width:860px){.mf-news{grid-template-columns:1fr;gap:22px;align-items:start}}
@media(max-width:520px){
  .mf-row{flex-direction:column}
  /* In a column, flex-basis is HEIGHT — the row rule's `flex:1 1 200px` turned the
     email field into a 200px-tall box on phones. Size it by its content here. */
  .mf-form input{flex:0 0 auto}
  .mf-form button{width:100%;justify-content:center}
}

/* ===== EMAIL CAPTURE POPUP (iOS glass) ===== */
.sub-ov{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;padding:22px;
  background:rgba(6,6,7,.5);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  opacity:0;visibility:hidden;transition:opacity .35s ease,visibility 0s .35s}
.sub-ov.open{opacity:1;visibility:visible;transition:opacity .35s ease,visibility 0s}
/* Smaller and flatter. The glassmorphism (34px backdrop blur + 200% saturate
   + an inset highlight) and the orange radial glow behind the heading were the
   two things making this read as a generated modal, and both fought the flat
   ground the rest of the site now uses. */
.sub-card{position:relative;width:100%;max-width:376px;border-radius:12px;overflow:hidden;padding:26px 24px 22px;
  text-align:center;color:#f4f1ec;
  background:#161618;
  border:1px solid rgba(255,255,255,.13);
  box-shadow:0 30px 70px -24px rgba(0,0,0,.7);
  transform:translateY(16px) scale(.95);transition:transform .4s cubic-bezier(.16,1,.3,1)}
.sub-ov.open .sub-card{transform:none}
.sub-badge{display:inline-flex;align-items:center;gap:7px;font-family:var(--sans);font-weight:600;font-size:.68rem;
  letter-spacing:.18em;text-transform:uppercase;color:#ffb59c;
  background:rgba(255,77,28,.14);border:none;padding:7px 14px;border-radius:6px;margin-bottom:18px}
.sub-badge svg{width:13px;height:13px}
.sub-card h2{font-size:1.4rem;line-height:1.1;margin:0 0 8px;color:#fff}
.sub-card h2 .em{color:var(--accent)}
.sub-card>p{color:#cfc9c0;font-size:.9rem;line-height:1.55;margin:0 auto 18px;max-width:30ch}
.sub-field{display:flex;flex-direction:column;gap:10px}
.sub-field input{width:100%;padding:12px 16px;border-radius:8px;border:1px solid rgba(255,255,255,.2);
  background:rgba(255,255,255,.08);color:#fff;font-family:var(--sans);font-size:.92rem;text-align:center}
.sub-field input::placeholder{color:rgba(255,255,255,.45)}
.sub-field input:focus{outline:none;border-color:var(--accent);background:rgba(255,255,255,.12)}
.sub-field .btn-primary{justify-content:center;width:100%;padding:12px}
.sub-err{color:#ff9d7f;font-size:.82rem;min-height:1em;margin-top:2px}
.sub-fine{color:rgba(255,255,255,.5);font-size:.74rem;margin-top:14px}
.sub-fine a{color:rgba(255,255,255,.7);text-decoration:underline}
.sub-close{position:absolute;top:12px;right:12px;width:29px;height:29px;border-radius:50%;
  background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.16);color:#fff;
  display:grid;place-items:center;cursor:pointer;transition:.22s;z-index:2}
.sub-close:hover{background:rgba(255,255,255,.2);transform:rotate(90deg)}
.sub-close svg{width:16px;height:16px}
.sub-card h2{transition:opacity .25s ease}
/* ---- success reveal (smooth cross-fade, no height jump) ---- */
.sub-badge,.sub-intro{transition:opacity .3s ease,max-height .4s ease,margin .4s ease,transform .3s ease;max-height:120px}
.sub-done .sub-badge,.sub-done .sub-intro{opacity:0;max-height:0;margin-top:0;margin-bottom:0;overflow:hidden;transform:translateY(-6px);pointer-events:none}
/* form + success share one grid cell so the card height stays put while they cross-fade */
.sub-stack{display:grid}
.sub-stack>*{grid-area:1/1}
.sub-field{transition:opacity .3s ease,transform .3s ease}
.sub-done .sub-field{opacity:0;transform:translateY(-8px) scale(.98);pointer-events:none}
.sub-success{opacity:0;transform:scale(.96);pointer-events:none;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  transition:opacity .4s .16s ease,transform .45s .16s cubic-bezier(.16,1,.3,1)}
.sub-done .sub-success{opacity:1;transform:none;pointer-events:auto}
.sub-check{width:72px;height:72px;border-radius:50%;margin:0 auto 16px;display:grid;place-items:center;position:relative;
  background:rgba(255,77,28,.15);border:1px solid rgba(255,77,28,.4);color:var(--accent)}
.sub-check svg{width:34px;height:34px}
/* THE TICK'S PATH DIRECTION IS THE ANIMATION DIRECTION. stroke-dashoffset
   reveals from the path's START POINT, so the `d` must begin at the SHORT
   arm (M4 12 -> l5 5 -> L20 6) for it to draw the way a tick is written.
   The stock icon path (M20 6 9 17l-5-5) starts at the long arm's tip and
   made it draw backwards. Do not swap this path for the shared one used by
   the static ticks elsewhere — those are not animated, this one is. */
.sub-check svg path{stroke-dasharray:30;stroke-dashoffset:30}
/* pop the circle, ripple a ring, then draw the tick */
.sub-done .sub-check{animation:tvPop .5s .3s cubic-bezier(.16,1,.3,1) both}
.sub-done .sub-check::after{content:"";position:absolute;inset:-2px;border-radius:50%;border:2px solid var(--accent);
  opacity:0;animation:tvRing .8s .45s ease-out forwards}
.sub-done .sub-check svg path{animation:tvDraw .5s .55s cubic-bezier(.65,0,.35,1) forwards}
.sub-msg{color:#cfc9c0;font-size:.98rem;line-height:1.5;max-width:30ch;margin:0 auto}
@keyframes tvPop{0%{transform:scale(.2);opacity:0}55%{transform:scale(1.14)}100%{transform:scale(1);opacity:1}}
@keyframes tvRing{0%{transform:scale(1);opacity:.85}100%{transform:scale(1.6);opacity:0}}
@keyframes tvDraw{to{stroke-dashoffset:0}}
@media(prefers-reduced-motion:reduce){.sub-done .sub-check,.sub-done .sub-check::after,.sub-done .sub-check svg path{animation:none}.sub-check svg path{stroke-dashoffset:0}}
/* Light mode. The card was written as one hardcoded dark glass — #fff type on a
   near-black pane — so on a light page the first-time popup came up as a dark slab
   whatever the theme said. Same glass treatment, light ground; the warm glow and
   the accent stay put, the glow just eased back so it doesn't muddy a pale card. */
:root[data-theme="light"] .sub-ov{background:rgba(20,19,17,.34)}
:root[data-theme="light"] .sub-card{color:var(--ink);
  background:#ffffff;border-color:rgba(0,0,0,.10);
  box-shadow:0 30px 70px -26px rgba(40,30,20,.3)}
:root[data-theme="light"] .sub-card h2{color:var(--ink)}
:root[data-theme="light"] .sub-card>p,
:root[data-theme="light"] .sub-msg{color:var(--muted)}
:root[data-theme="light"] .sub-badge{color:#a8380f;background:rgba(255,77,28,.12)}
:root[data-theme="light"] .sub-field input{background:rgba(255,255,255,.78);
  border-color:rgba(0,0,0,.14);color:var(--ink)}
:root[data-theme="light"] .sub-field input::placeholder{color:var(--faint)}
:root[data-theme="light"] .sub-field input:focus{background:#fff;border-color:var(--accent)}
:root[data-theme="light"] .sub-err{color:#b3300f}
:root[data-theme="light"] .sub-fine{color:var(--faint)}
:root[data-theme="light"] .sub-fine a{color:var(--muted)}
:root[data-theme="light"] .sub-close{background:rgba(0,0,0,.06);border-color:rgba(0,0,0,.12);color:var(--ink)}
:root[data-theme="light"] .sub-close:hover{background:rgba(0,0,0,.12)}
@media(max-width:480px){.sub-card{padding:32px 22px 26px}.sub-card h2{font-size:1.6rem}}

/* ===== LEGAL / LONG-FORM PROSE ===== */
.legal{max-width:760px;margin:0 auto;padding:0 0 20px}
.legal .upd{color:var(--faint);font-size:.85rem;margin-bottom:34px}
.legal h2{font-family:var(--serif);font-weight:700;font-size:1.35rem;letter-spacing:-.01em;color:var(--ink);margin:38px 0 12px}
.legal h3{font-size:1.05rem;margin:22px 0 8px;color:var(--ink)}
.legal p,.legal li{color:var(--muted);font-size:.98rem;line-height:1.75;margin-bottom:12px}
.legal ul{padding-left:22px;margin-bottom:14px}
.legal li{margin-bottom:6px}
.legal a{color:var(--accent);text-decoration:underline;text-underline-offset:2px}

/* ===== JOURNAL GRID ===== */
.jr-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
@media(max-width:900px){.jr-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.jr-grid{grid-template-columns:1fr}}
.jr-card{border:1px solid var(--line);border-radius:var(--r);background:var(--bg2);padding:26px;position:relative;
  display:flex;flex-direction:column;gap:12px;transition:.28s;overflow:hidden}
.jr-card:hover{transform:translateY(-4px);border-color:rgba(255,77,28,.4);box-shadow:0 24px 50px -24px rgba(0,0,0,.5)}
.jr-cat{font-family:var(--sans);font-weight:600;font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}
.jr-card h3{font-size:1.22rem;line-height:1.15}
.jr-card p{color:var(--muted);font-size:.92rem;line-height:1.55;flex:1}
.jr-meta{display:flex;align-items:center;gap:10px;color:var(--faint);font-size:.8rem;margin-top:4px}
.jr-soon{position:absolute;top:16px;right:16px;font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--gold);background:rgba(245,179,1,.12);border:1px solid rgba(245,179,1,.3);padding:4px 10px;border-radius:6px}

/* ===== CAREERS / SIMPLE ROLE ROWS ===== */
.role-row{display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap;
  padding:22px 26px;border:1px solid var(--line);border-radius:var(--r);background:var(--bg2);margin-bottom:14px;transition:.24s}
.role-row:hover{border-color:rgba(255,77,28,.4);transform:translateX(3px)}
.role-row h3{font-size:1.15rem;margin-bottom:4px}
.role-row .rr-meta{color:var(--muted);font-size:.86rem}
.role-row .rr-tags{display:flex;gap:8px;flex-wrap:wrap}
.role-row .rr-tags span{font-size:.74rem;background:var(--bg3);border:1px solid var(--line);padding:5px 11px;border-radius:6px;color:var(--muted)}

/* reveal — OFF by request: nothing fades or slides in as you scroll. Every section
   is simply there the moment it is laid out. The .rv class and the observer that
   adds .in are both left in place (other renderers call them) — they now have
   nothing to do, and content no longer depends on JS running to become visible. */
.rv,.rv.in{opacity:1;transform:none;transition:none}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}


/* ============ BRAND ART (replaces photo) ============ */
.brand-art{position:relative;width:min(400px,86vw);aspect-ratio:4/5;border-radius:16px;overflow:hidden;
  border:1px solid var(--line);background:
   radial-gradient(120% 90% at 80% 0%,rgba(255,77,28,.22),transparent 55%),
   radial-gradient(120% 90% at 10% 100%,rgba(122,43,255,.20),transparent 55%),
   var(--bg2);box-shadow:0 40px 90px rgba(0,0,0,.5);justify-self:center}
.ba-grid{position:absolute;inset:0;opacity:.5;
  background-image:linear-gradient(var(--line2) 1px,transparent 1px),linear-gradient(90deg,var(--line2) 1px,transparent 1px);
  background-size:38px 38px;-webkit-mask-image:radial-gradient(circle at 50% 45%,#000,transparent 78%);
  mask-image:radial-gradient(circle at 50% 45%,#000,transparent 78%)}
.ba-ring{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:74%;aspect-ratio:1;border-radius:50%;
  border:1px dashed rgba(255,77,28,.35);animation:spinorb 26s linear infinite}
.ba-ring::before{content:"";position:absolute;top:-5px;left:50%;width:9px;height:9px;border-radius:50%;background:var(--accent);box-shadow:0 0 14px var(--accent)}
.ba-mark{position:absolute;top:50%;left:50%;transform:translate(-50%,-58%);width:44%;filter:drop-shadow(0 14px 40px rgba(255,77,28,.4))}
.ba-mark svg{width:100%;height:auto;display:block}
.ba-word{position:absolute;top:calc(50% + 66px);left:0;right:0;text-align:center;font-family:var(--serif);font-weight:800;
  font-size:1.5rem;letter-spacing:.02em;color:var(--ink)}
.ba-word b{background:linear-gradient(120deg,var(--accent),var(--gold));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.ba-tag{position:absolute;left:0;right:0;bottom:64px;text-align:center;font-size:.72rem;letter-spacing:.26em;text-transform:uppercase;color:var(--muted)}
/* actual logo inside brand tile (calm motion) */
.ba-logo{position:absolute;top:46%;left:50%;width:46%;max-width:172px;border-radius:50%;transform:translate(-50%,-50%);
  filter:drop-shadow(0 22px 46px rgba(255,110,20,.4));animation:baFloat 7s ease-in-out infinite;z-index:2}
@keyframes baFloat{0%,100%{transform:translate(-50%,-50%)}50%{transform:translate(-50%,-56%)}}
.ba-halo{position:absolute;top:46%;left:50%;width:74%;aspect-ratio:1;transform:translate(-50%,-50%);border-radius:50%;
  background:radial-gradient(circle,rgba(255,120,28,.34),transparent 66%);filter:blur(8px);animation:baPulse 6s ease-in-out infinite;z-index:1}
@keyframes baPulse{0%,100%{opacity:.5;transform:translate(-50%,-50%) scale(1)}50%{opacity:.9;transform:translate(-50%,-50%) scale(1.07)}}
@media(prefers-reduced-motion:reduce){.ba-logo,.ba-halo{animation:none}}
.ba-chips{position:absolute;bottom:18px;left:18px;right:18px;z-index:3;display:flex;gap:10px;justify-content:center}
.ba-chips span{flex:1;text-align:center;padding:11px 8px;border-radius:10px;background:rgba(12,12,14,.55);
  backdrop-filter:blur(10px);border:1px solid var(--line);font-size:.8rem;font-weight:600;color:var(--ink);display:flex;align-items:center;justify-content:center;gap:8px}
:root[data-theme="light"] .ba-chips span{background:rgba(255,255,255,.6)}
.ba-chips span svg{width:15px;height:15px;color:var(--accent)}
.ba-node{position:absolute;width:7px;height:7px;border-radius:50%;background:var(--gold);opacity:.8;animation:floaty 5s ease-in-out infinite}
.ba-node.n1{top:16%;left:18%} .ba-node.n2{top:24%;right:16%;animation-delay:1.2s;background:var(--accent)}
.ba-node.n3{top:70%;left:22%;animation-delay:.6s;background:var(--accent)} .ba-node.n4{top:64%;right:20%;animation-delay:1.8s}
@keyframes floaty{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}
.brand-orb{position:absolute;width:88px;height:88px;border-radius:50%;background:var(--accent);display:grid;place-items:center;
  top:-24px;right:-18px;z-index:4;color:#fff;font-family:var(--serif);font-weight:700;font-size:.72rem;text-align:center;line-height:1.2;
  box-shadow:0 14px 34px rgba(255,77,28,.45);animation:spinorb 18s linear infinite}
.brand-orb span{animation:spinorb 18s linear infinite reverse}

/* ===== about: studio identity card =====
   Deliberately quiet, and built from the same parts as every other card on the site
   (--bg2 surface, 1px --line border, --r radius). The old version span a dashed ring,
   pulsed a glow and floated the monogram all at once, with gradient-filled numerals
   repeating figures the page already states twice below. Facts, not effects. */
.brand-card{position:relative;width:min(400px,100%);padding:30px;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--r);background:var(--bg2)}
/* one soft accent wash so it is not a flat grey slab in a dark page */
.brand-card::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 80% at 88% -10%,rgba(255,77,28,.10),transparent 60%)}
.bc-head{position:relative;display:flex;align-items:center;gap:14px;
  padding-bottom:22px;border-bottom:1px solid var(--line)}
.bc-mark{height:34px;width:auto;flex-shrink:0}
:root[data-theme="light"] .bc-mark{filter:invert(1)}
.bc-name{font-family:var(--serif);font-weight:800;font-size:1.34rem;letter-spacing:-.01em}
.bc-name span{color:var(--accent)}          /* same lockup as the nav, no gradient text */
.bc-role{margin-top:3px;font-size:.7rem;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted)}
/* a spec panel: labels hold their own column so the values line up down the card */
.bc-facts{position:relative}
.bc-facts>div{display:grid;grid-template-columns:92px 1fr;gap:16px;align-items:baseline;
  padding:14px 0;border-bottom:1px solid var(--line2)}
.bc-facts>div:last-child{border-bottom:0;padding-bottom:0}
.bc-facts dt{font-size:.7rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--faint)}
.bc-facts dd{font-size:.94rem;color:var(--ink);line-height:1.45}
@media(max-width:430px){
  .brand-card{padding:24px}
  .bc-facts>div{grid-template-columns:1fr;gap:4px;padding:12px 0}
  .bc-facts dd{font-size:.9rem}
}

/* dual pillars strip */
.pillars{display:grid;grid-template-columns:1fr 1fr;gap:20px}
@media(max-width:760px){.pillars{grid-template-columns:1fr}}
.pillar{padding:34px;border:1px solid var(--line);border-radius:var(--r);background:var(--bg2);position:relative;overflow:hidden;transition:.35s}
.pillar:hover{transform:translateY(-4px);border-color:rgba(255,77,28,.4)}
.pillar .pic{width:52px;height:52px;border-radius:10px;background:var(--bg3);border:1px solid var(--line);display:grid;place-items:center;color:var(--accent);margin-bottom:18px}
.pillar .pic svg{width:26px;height:26px}
.pillar h3{font-size:1.5rem;margin-bottom:10px}
.pillar p{color:var(--muted);font-size:.98rem;margin-bottom:16px}
.pillar .tags{display:flex;flex-wrap:wrap;gap:7px}
.pillar .tags span{font-size:.76rem;color:var(--ink);background:var(--bg3);border:1px solid var(--line);padding:5px 11px;border-radius:6px}

/* ============ SOFTWARE BUILDS ============ */
.build-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
@media(max-width:900px){.build-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.build-grid{grid-template-columns:1fr}}
/* mobile-only: sticky stacking project cards (desktop grid untouched) */
@media(max-width:560px){
  .build-grid{display:block}
  .build-grid>.build{position:sticky;top:calc(80px + var(--i,0)*16px);margin-bottom:20px;
    box-shadow:0 22px 46px rgba(0,0,0,.5)}
  .build-grid>.build:last-child{margin-bottom:0}
  .build-grid>.build:hover{transform:none}
  .build-grid>.build .device{transition:none}
  /* tap-to-open: collapse the tall deck to a single peek until the visitor opts in */
  .build-grid.collapsible:not(.open){max-height:82vh;overflow:hidden;
    -webkit-mask-image:linear-gradient(180deg,#000 64%,transparent);
            mask-image:linear-gradient(180deg,#000 64%,transparent)}
  .build-grid.collapsible:not(.open)>.build{position:relative;top:auto;margin-bottom:16px}
  .build-grid+.work-toggle{display:flex}
  .build-grid+.work-toggle[hidden]{display:none}
}
.build{border:1px solid var(--line);border-radius:var(--r);background:var(--bg2);overflow:hidden;display:flex;flex-direction:column;transition:transform .4s,border-color .4s;position:relative}
.build:hover{transform:translateY(-6px);border-color:rgba(255,77,28,.5)}
.build-cover{position:relative;aspect-ratio:16/10;overflow:hidden;
  background:radial-gradient(135% 130% at 50% -15%,var(--bg3),var(--bg2));
  display:flex;justify-content:center;align-items:flex-start;padding:22px 22px 0}
:root[data-theme="dark"] .build-cover{background:radial-gradient(135% 130% at 50% -15%,#191920,#0e0e12)}
.device{position:relative;background:#fff;overflow:hidden;transition:transform .7s cubic-bezier(.2,.7,.2,1)}
.build:hover .device{transform:translateY(-4px)}
/* browser frame (desktop previews) */
/* no drop shadow behind the mockups — removed on request; the frame border alone separates them */
.device.browser{width:100%;border-radius:10px 12px 0 0;border:1px solid rgba(0,0,0,.10)}
:root[data-theme="dark"] .device.browser{border-color:#2a2a31}
.dev-bar{display:flex;align-items:center;gap:6px;height:29px;padding:0 12px;background:linear-gradient(#f6f6f8,#e9e9ef);border-bottom:1px solid rgba(0,0,0,.07)}
.dev-bar b{width:9px;height:9px;border-radius:50%;background:#ec6a5e;flex:none}
.dev-bar b:nth-of-type(2){background:#f4bf4f}
.dev-bar b:nth-of-type(3){background:#61c554}
.dev-bar i{margin-left:10px;flex:1;height:17px;border-radius:4px;background:#fff;border:1px solid rgba(0,0,0,.08);
  font-style:normal;font-size:.6rem;color:#8b8b92;padding:0 9px;font-family:var(--sans);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:5px}
.dev-bar i svg{width:10px;height:10px;flex:none;opacity:.55}
.dev-screen{position:relative;width:100%;aspect-ratio:16/10;overflow:hidden;background:#fff}
.dev-screen img{width:100%;height:auto;display:block}
/* phone frame (mobile previews) */
.device.phone{width:auto;height:132%;aspect-ratio:.475;border-radius:26px;padding:22px 8px 12px;
  background:#0c0c0f;border:1px solid #2a2a30}
.device.phone::before{content:"";position:absolute;top:9px;left:50%;transform:translateX(-50%);width:26%;height:6px;border-radius:100px;background:#26262c;z-index:4}
.device.phone .dev-screen{height:100%;width:100%;aspect-ratio:auto;border-radius:12px}
.device.phone .dev-screen img{height:100%;width:100%;object-fit:cover;object-position:top center}
.build-cover .ct{position:absolute;bottom:14px;left:14px;z-index:6;font-size:.62rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:#fff;background:rgba(10,8,6,.82);border:1px solid rgba(255,255,255,.22);padding:5px 10px;border-radius:6px}
.build-cover .live{position:absolute;bottom:14px;right:14px;z-index:6;font-size:.62rem;font-weight:700;color:#fff;
  /* PERF: no backdrop-filter on these two badges. They sit over the screenshot, and on
     phones the cards stack as sticky layers, so every scroll frame re-blurred every
     badge over a moving image — the main cause of the Software page lagging. */
  background:rgba(10,8,6,.82);border:1px solid rgba(255,255,255,.22);padding:5px 10px 5px 8px;border-radius:6px;display:flex;align-items:center;gap:6px}
.build-cover .live b{width:6px;height:6px;border-radius:50%;background:#38d17a;box-shadow:0 0 8px #38d17a}
.build-body{padding:24px;display:flex;flex-direction:column;flex:1}
.build-body h3{font-size:1.28rem;margin-bottom:4px}
.build-body .role{font-size:.78rem;color:var(--accent);font-weight:600;margin-bottom:12px}
.build-body p{color:var(--muted);font-size:.92rem;margin-bottom:18px;flex:1}
.build-tech{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:16px}
.build-tech span{font-size:.72rem;font-family:var(--sans);color:var(--ink);background:var(--bg3);border:1px solid var(--line);padding:4px 10px;border-radius:6px}
.build-link{display:inline-flex;align-items:center;gap:7px;font-size:.86rem;font-weight:600;color:var(--accent);align-self:flex-start}
.build-link svg{width:15px;height:15px;transition:.25s}
.build-link:hover svg{transform:translate(2px,-2px)}
.build-link.dis{color:var(--faint);pointer-events:none}

/* tech stack strip */
.stack{display:flex;flex-wrap:wrap;gap:10px;justify-content:center}
.stack span{font-size:.86rem;font-weight:500;color:var(--muted);background:var(--bg2);border:1px solid var(--line);padding:10px 18px;border-radius:8px}
.stack span:hover{color:var(--ink);border-color:var(--accent)}

/* testimonials */
.tst-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
@media(max-width:900px){.tst-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.tst-grid{grid-template-columns:1fr}}
.tst{border:1px solid var(--line);border-radius:var(--r);background:var(--bg);padding:26px 24px;
  display:flex;flex-direction:column;gap:15px;transition:transform .35s,border-color .35s}
.tst:hover{transform:translateY(-4px);border-color:rgba(255,77,28,.45)}
.tst .stars{display:flex;gap:3px;color:var(--gold)}
.tst .stars svg{width:16px;height:16px}
.tst>p{color:var(--ink);font-size:.97rem;line-height:1.6;font-weight:300;flex:1;margin:0}
.tst .who{display:flex;align-items:center;gap:12px}
.tst .av{width:42px;height:42px;border-radius:50%;flex:none;display:grid;place-items:center;
  font-family:var(--serif);font-weight:700;font-size:.92rem;color:#fff;
  background:linear-gradient(135deg,var(--accent),var(--gold));box-shadow:0 6px 16px rgba(255,77,28,.32)}
.tst .who-t{display:flex;flex-direction:column;line-height:1.3}
.tst .nm{font-family:var(--sans);font-weight:600;font-size:.9rem;color:var(--ink)}
.tst .rl{font-size:.78rem;color:var(--muted)}

/* ============================================================
   HOMEPAGE, CLEAN / MODERN RESTYLE  (scoped to body.re)
   Applied to index.html first; roll out to other pages once approved.
   Goal: simple, clean, bold, modern, bold via type + whitespace, not decoration.
   ============================================================ */
/* calmer surface: drop the grain, keep only a whisper of the glow */
body.re .grain{display:none}
body.re .glow.a{opacity:.12}
body.re .glow.b{opacity:.05}

/* bold display headlines on the Syne display face */
body.re .hero h1,
body.re .sec-head h2,
body.re .cta h2{font-family:var(--serif);font-weight:800;letter-spacing:-.02em;line-height:1.04}
body.re .hero h1{font-size:clamp(2.3rem,5.6vw,4rem);letter-spacing:-.025em;line-height:1.04;margin-bottom:22px}
/* keep long words (e.g. "impossible") inside the viewport on phones.
   pure-vw sizing keeps the word-to-viewport ratio constant, so if it fits
   at one width it fits at all widths — no fixed rem floor to overflow. */
body.re .hero h1{overflow-wrap:break-word}
@media(max-width:560px){
  body.re .hero h1{font-size:min(7.6vw,2.5rem);line-height:1.07;letter-spacing:-.02em}
}
body.re .sec-head h2{font-size:var(--fs-h);line-height:var(--lh-h);margin:12px 0 16px}
/* orange→gold gradient accent, matching the other pages */
body.re .hero h1 .em,
body.re .cta h2 .em,
body.re .sec-head h2 .em{background:linear-gradient(120deg,var(--accent),var(--gold));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}

/* more air between sections */
body.re .sec-pad{padding:80px 0}
body.re .hero-solo{padding:136px 0 96px}
@media(max-width:860px){body.re .hero-solo{padding:104px 0 60px}}
body.re .sec-head{margin-bottom:44px}
body.re .hero-desc{font-size:var(--fs-sub);line-height:var(--lh-sub)}

/* quieter, modern section labels */
body.re .sec-num{font-family:var(--sans);letter-spacing:.16em;text-transform:uppercase;font-size:.72rem;font-weight:600;color:var(--faint)}

/* lighter borders for a cleaner surface */
body.re .pillar,body.re .build,body.re .tst{border-color:var(--line2)}

/* ---- IN REAL LIFE : always-dark product-experience band (Apple-style) ---- */
.irl{background:var(--panel);color:var(--panel-ink);padding:clamp(52px,6.5vw,84px) 0;position:relative;overflow:hidden}
.irl::before{content:"";position:absolute;left:27%;top:50%;width:46%;height:82%;transform:translate(-50%,-50%);
  background:radial-gradient(circle,rgba(255,77,28,.15),transparent 66%);filter:blur(26px);pointer-events:none}
.irl-in{display:grid;grid-template-columns:1fr 1.1fr;gap:clamp(28px,5vw,64px);align-items:center;position:relative}
.irl-photo{position:relative;display:flex;justify-content:center}
.irl-photo img{display:block;width:100%;max-width:480px;height:auto;margin:0 auto;
  border-radius:12px;border:1px solid rgba(255,255,255,.09);box-shadow:0 40px 84px -32px rgba(0,0,0,.65)}
.irl-copy .sec-num{color:#8f8a80;font-family:var(--sans);letter-spacing:.16em;text-transform:uppercase;font-size:.72rem;font-weight:600}
.irl-copy h2{font-family:var(--serif);font-weight:800;letter-spacing:-.02em;line-height:1.04;
  font-size:clamp(2rem,4.4vw,3.05rem);color:#fff;margin:14px 0 18px}
.irl-copy h2 .em{background:linear-gradient(120deg,var(--accent),var(--gold));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}
.irl-copy p{color:#b9b4ab;font-size:1.06rem;line-height:1.6;max-width:48ch}
.irl-stats{display:flex;gap:44px;margin-top:34px}
.irl-stats .n{font-family:var(--serif);font-weight:800;font-size:clamp(1.9rem,4vw,2.6rem);line-height:1;color:#fff}
.irl-stats .n span{color:var(--accent)}
.irl-stats .l{color:#8f8a80;font-size:.82rem;margin-top:7px;letter-spacing:.02em}
@media(max-width:760px){
  .irl-in{grid-template-columns:1fr;gap:14px}
  .irl-photo{max-width:340px;margin:0 auto;order:-1}
  .irl-stats{gap:32px;margin-top:26px}
}
/* .duo = two rows inside ONE black band, the second mirrored. One background, one set
   of section padding; the rows are separated by their own margin rather than by two
   sections butting together, so it reads as a single stretch of black. */
.irl.duo .irl-in + .irl-in{margin-top:clamp(44px,5.6vw,78px)}
/* the glow is parked behind the photo, so a two-row band needs one per row - ::before
   sits behind the upper-left photo, ::after behind the lower-right one */
.irl.duo::before{top:27%;height:46%}
.irl.duo::after{content:"";position:absolute;right:27%;top:73%;width:46%;height:46%;
  transform:translate(50%,-50%);background:radial-gradient(circle,rgba(255,77,28,.13),transparent 66%);
  filter:blur(26px);pointer-events:none}
@media(min-width:761px){
  .irl-in.rev{grid-template-columns:1.1fr 1fr}
  .irl-in.rev .irl-photo{order:2}
  .irl-in.rev .irl-copy{order:1}
}
@media(max-width:760px){
  /* stacked, the two glows would pile up in the middle of a very tall band */
  .irl.duo::before{top:25%;height:38%}
  .irl.duo::after{top:75%;height:38%;right:auto;left:27%;transform:translate(-50%,-50%)}
}
/* the feelings list that stands in for the stat row on the mirrored band - deliberately
   words, not numbers: nothing here should read as a measured figure */
.irl-feel{list-style:none;margin:30px 0 0;padding:0;display:grid;gap:13px;max-width:44ch}
.irl-feel li{position:relative;padding-left:26px;color:#cfcac2;font-size:1.02rem;line-height:1.5}
.irl-feel li::before{content:"";position:absolute;left:0;top:.55em;width:9px;height:9px;border-radius:50%;
  background:linear-gradient(120deg,var(--accent),var(--gold))}
@media(max-width:760px){.irl-feel{margin-top:24px;gap:11px}.irl-feel li{font-size:.96rem}}

/* design-work IRL-style bands (outdoor · stationery), landscape photos, alternating */
.dw-irl{padding:clamp(46px,6.5vw,86px) 0}
.dw-irl .irl-photo img{max-width:none;width:100%;margin:0}
@media(min-width:761px){
  .dw-irl .irl-in{grid-template-columns:1.32fr minmax(0,.8fr)}
  .dw-irl.rev .irl-in{grid-template-columns:minmax(0,.8fr) 1.32fr}
  .dw-irl.rev .irl-photo{order:2}
  .dw-irl.rev .irl-copy{order:1}
  .dw-irl.rev::before{left:auto;right:27%}
}
/* light variant, near-white with a faint brand-green wash */
.dw-irl.light{background:#e7e7e7;color:#1a1c17}
.dw-irl.light::before{background:none}
.dw-irl.light .sec-num{color:#6d7a63}
.dw-irl.light .irl-copy h2{color:#161811}
.dw-irl.light .irl-copy p{color:#4c5145}
.dw-irl.light .irl-photo img{border:1px solid rgba(0,0,0,.07);box-shadow:none}
/* mobile: enlarge the stationery flat-lay so it bleeds off both screen edges equally
   (.irl overflow:hidden clips it to the viewport); section bg is #e7e7e7 (color-picked
   from the photo) and the green drop-shadow is dropped so image and section blend seamlessly */
@media(max-width:760px){
  .dw-irl.light .irl-photo{max-width:none;width:120vw;margin:0 0 0 calc(50% - 60vw)}
  .dw-irl.light .irl-photo img{border-radius:0;border:none;box-shadow:none}
}

/* ===== PRODUCT SHOWCASE (split · creative) ===== */
.showcase{background:transparent}
.show{max-width:var(--maxw);margin:0 auto;padding:clamp(58px,9vw,120px) 24px;position:relative;
  display:grid;grid-template-columns:1fr 1.08fr;align-items:center;gap:clamp(26px,4.4vw,64px)}
/* the picture carries the section, so whichever side it is on gets the wider track */
.show.rev{grid-template-columns:1.08fr 1fr}
.show.rev .show-copy{order:2}
.show.rev .show-shot{order:1}
.show-copy{position:relative;z-index:2}
.show-kicker{display:inline-flex;align-items:center;font-family:var(--sans);font-weight:600;
  font-size:.72rem;letter-spacing:.22em;text-transform:uppercase;color:var(--accent);margin-bottom:18px}
.show-kicker::before{content:none}
.show h2{font-family:var(--serif);font-weight:800;letter-spacing:-.03em;line-height:.97;
  font-size:clamp(2.1rem,4.8vw,3.9rem);text-wrap:balance}
.show h2 .em{font-style:normal;background:linear-gradient(120deg,var(--accent),var(--gold));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}
.show p{color:var(--muted);font-size:clamp(1rem,1.5vw,1.16rem);line-height:1.55;max-width:42ch;margin:22px 0 0;font-weight:300}
.show-shot{position:relative;z-index:2}
.show-shot img{width:100%;height:auto;display:block;filter:drop-shadow(0 38px 70px rgba(20,15,10,.26));
  transition:transform .8s cubic-bezier(.2,.7,.2,1)}
.show:hover .show-shot img{transform:translateY(-7px)}
:root[data-theme="dark"] .show-shot img{filter:drop-shadow(0 44px 82px rgba(0,0,0,.6))}
/* The mockup used to bleed toward the outer edge with a one-sided negative margin. It
   pulled the pair off the page centre line at every desktop width - at 1550px the block
   sat 61px left of centre, 93px of air on its left against 216px on its right - so the
   section never read as balanced. It now sits square inside the same container every
   other section uses, which keeps the margins equal at every width. */
.show:not(.rev) .show-shot{margin-right:0}
.show.rev .show-shot{margin-left:0}
@media(max-width:820px){
  /* .show.rev above is more specific than a bare .show, and a media query adds no
     specificity - so the single-column stack has to name both or the phone keeps
     the two-column grid and the mockup hangs off the side of the screen. */
  .show,.show.rev{grid-template-columns:1fr;gap:26px;padding:clamp(50px,12vw,80px) 24px;text-align:center}
  .show-copy,.show.rev .show-copy{order:1}
  .show:not(.rev) .show-shot,.show.rev .show-shot{order:2;margin:0}
  .show-kicker{justify-content:center}
  .show p{margin-left:auto;margin-right:auto}
}

/* ---- story lead ---- */
.showcase.design{padding:clamp(40px,6vw,72px) 0 clamp(0px,2vw,18px)}
.showcase.software{padding-top:clamp(58px,8vw,108px);padding-bottom:clamp(40px,7vw,86px)}
.show-lead{max-width:660px;margin:0 auto;text-align:center;padding:0 24px}
.show-lead .show-kicker{justify-content:center}
.show-lead h2{font-family:var(--serif);font-weight:800;letter-spacing:-.03em;line-height:1;
  font-size:clamp(2.1rem,5.6vw,3.5rem);text-wrap:balance}
.show-lead h2 .em{font-style:normal;background:linear-gradient(120deg,var(--accent),var(--gold));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}
.show-lead p{color:var(--muted);font-size:clamp(1rem,1.6vw,1.14rem);line-height:1.55;margin:16px auto 0;max-width:52ch;font-weight:300}
.showcase.software .show{padding-top:clamp(24px,4vw,52px);padding-bottom:clamp(24px,4vw,52px)}
/* full-width showcase image (no copy beside it) */
.show-full{max-width:var(--maxw);margin:0 auto;padding:clamp(28px,4.5vw,60px) 24px}
.show-full img{width:100%;height:auto;display:block;
  filter:drop-shadow(0 38px 70px rgba(20,15,10,.26));transition:transform .8s cubic-bezier(.2,.7,.2,1)}
.show-full:hover img{transform:translateY(-7px)}
:root[data-theme="dark"] .show-full img{filter:drop-shadow(0 44px 82px rgba(0,0,0,.6))}

/* ---- flyer spotlight (replaces the old scrolling flyer marquee) ----
   One campaign on stage at a time: the flyer set IS the card, its story sits on
   the artwork, and the campaigns either side peek in at the edges. The cards are
   square because every set is a square 3x3 grid — nothing gets cropped away.
   Horizontal scroll-snap does the moving, so it drags on touch and scrolls with a
   trackpad; the dots in .fx-ui just drive the same scroll (there are no arrows).
   The track's side padding is half the leftover width, so any slide can sit dead
   centre — that padding is a % of the track, which is exactly the width snap
   centres against, so the maths stays right with a scrollbar on screen. The strip
   itself is tripled in JS, which is what keeps a flyer peeking on BOTH sides. */
.fx{--fxw:min(520px,62vw);--fxgap:clamp(14px,2.2vw,30px);
  margin-top:clamp(34px,5vw,62px);position:relative}
.fx-track{display:flex;gap:var(--fxgap);overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;scroll-behavior:smooth;
  padding:6px calc(50% - var(--fxw)/2) 10px;
  scrollbar-width:none;-ms-overflow-style:none}
.fx-track::-webkit-scrollbar{display:none}
.fx-track:focus{outline:none}
.fx-track:focus-visible{outline:2px solid var(--accent);outline-offset:6px;border-radius:16px}
.fx-slide{flex:0 0 var(--fxw);scroll-snap-align:center;scroll-snap-stop:always}

.fx-card{position:relative;overflow:hidden;border-radius:clamp(16px,1.8vw,24px);
  aspect-ratio:1;isolation:isolate;
  transform:scale(.88);opacity:.34;filter:saturate(.5);
  transition:transform .6s cubic-bezier(.2,.7,.2,1),opacity .6s,filter .6s}
.fx-slide.is-on .fx-card{transform:none;opacity:1;filter:none}
/* the peeking neighbours are the control: tapping one brings it on stage, so
   they have to look pressable and lift a little when a real pointer is over. */
.fx-slide:not(.is-on) .fx-card{cursor:pointer}
@media(hover:hover){.fx-slide:not(.is-on) .fx-card:hover{transform:scale(.92);opacity:.62;filter:saturate(.8)}}
.fx-shot{width:100%;height:100%;object-fit:cover;display:block}

/* the story sits on the artwork, so the foot of the flyer is shaded just enough
   to hold white type — the rest of the set stays untouched */
.fx-card::after{content:"";position:absolute;left:0;right:0;bottom:0;height:48%;z-index:1;
  pointer-events:none;
  background:linear-gradient(180deg,rgba(8,6,5,0) 0%,rgba(8,6,5,.3) 30%,rgba(8,6,5,.86) 52%,rgba(8,6,5,.97) 100%)}

.fx-copy{position:absolute;z-index:2;left:0;right:0;bottom:0;
  padding:clamp(16px,2.4vw,30px);color:#f4f1ec;
  text-shadow:0 1px 14px rgba(0,0,0,.5)}
.fx-kicker{display:block;font-family:var(--sans);font-weight:600;font-size:.68rem;
  letter-spacing:.18em;text-transform:uppercase;
  background:linear-gradient(120deg,var(--accent),var(--gold));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;
  text-shadow:none}
.fx-kicker i{font-style:normal;-webkit-text-fill-color:rgba(244,241,236,.6);color:rgba(244,241,236,.6)}
.fx-copy h3{font-family:var(--serif);font-weight:800;letter-spacing:-.03em;line-height:1;
  font-size:clamp(1.35rem,2.4vw,2.1rem);margin:10px 0 0;color:#fff}
.fx-copy p{font-size:clamp(.8rem,1vw,.95rem);line-height:1.5;font-weight:400;
  color:rgba(244,241,236,.86);margin:10px 0 0;max-width:56ch}

/* controls */
.fx-ui{display:flex;align-items:center;justify-content:center;gap:clamp(12px,2vw,20px);
  margin-top:clamp(18px,2.6vw,30px);padding:0 24px}
.fx-dots{display:flex;align-items:center;gap:9px;flex-wrap:wrap;justify-content:center}
.fx-dot{width:8px;height:8px;border-radius:999px;cursor:pointer;border:0;padding:0;
  background:var(--line);transition:width .3s,background .3s}
.fx-dot:hover{background:var(--faint)}
.fx-dot.on{width:26px;background:linear-gradient(120deg,var(--accent),var(--gold))}

/* phones: near-full-width cards, the neighbours reduced to a hint at the edge.
   The same words take a much bigger share of a small square, so the type steps
   down, the story is clamped to three lines and the shade rises to match — the
   copy must never sit on bare artwork. */
@media(max-width:760px){
  /* 86vw left ~7vw a side, which read as a sliver rather than a neighbouring
     flyer. 76vw gives ~12vw each side — enough to see there is a set either way. */
  .fx{--fxw:min(360px,76vw)}
  .fx-card{border-radius:10px}
  .fx-card::after{height:62%;
    background:linear-gradient(180deg,rgba(8,6,5,0) 0%,rgba(8,6,5,.28) 22%,rgba(8,6,5,.88) 42%,rgba(8,6,5,.97) 100%)}
  .fx-copy{padding:14px 16px 17px}
  .fx-copy h3{font-size:1.28rem;margin-top:7px}
  .fx-copy p{font-size:.78rem;line-height:1.45;margin-top:7px;
    display:-webkit-box;-webkit-line-clamp:3;line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
}
@media(prefers-reduced-motion:reduce){
  .fx-track{scroll-behavior:auto}
  .fx-card{transition:none}
}

/* ---- design work (bold floating cutouts + framed photo cards) ---- */
.dwork{max-width:100%;margin:clamp(38px,5vw,64px) auto 0;padding:0;
  display:flex;flex-direction:column;gap:clamp(20px,3vw,44px);align-items:center;position:relative}
.dw-item{position:relative;margin:0;width:100%;display:flex;flex-direction:column;align-items:center}
.dw-head{text-align:center;margin-bottom:clamp(16px,2.2vw,28px);padding:0 24px}
.dw-cat{display:block;font-family:var(--serif);font-weight:800;letter-spacing:-.02em;color:var(--ink);
  font-size:clamp(1.2rem,2vw,1.6rem);line-height:1.05;margin-bottom:5px}
.dw-head p{font-family:var(--sans);font-weight:400;line-height:1.4;color:var(--muted);
  font-size:clamp(.85rem,1.25vw,.97rem);max-width:34ch;margin:0 auto}
/* desktop-only duplicate of the Campaign caption, shown inside the white band */
.dw-head-desk{display:none}

/* framed photo cards (outdoor, stationery), matching the "In real life" frame */
.dw-frame .dw-media{display:flex;justify-content:center}
.dw-frame .dw-media img{width:100%;height:auto;border-radius:12px;border:1px solid var(--line);
  box-shadow:0 34px 70px -30px rgba(20,15,10,.5);transition:transform .6s cubic-bezier(.2,.7,.2,1)}
:root[data-theme="dark"] .dw-frame .dw-media img{box-shadow:0 40px 84px -32px rgba(0,0,0,.65)}
.dw-frame:hover .dw-media img{transform:translateY(-6px)}

/* stacked oversized cutouts: billboard full-bleed, roll-up big below it */
.dw-pop .dw-media,.dw-feature .dw-media{display:flex;justify-content:center;align-items:center;width:100%}
.dw-pop .dw-media img,.dw-feature .dw-media img{height:auto;
  transition:transform .6s cubic-bezier(.2,.7,.2,1)}
/* Campaign billboard, sized down, centered */
.dw-pop .dw-media{width:100%}
.dw-pop .dw-media img{width:clamp(540px,62vw,900px);max-width:100%;
  filter:drop-shadow(0 30px 54px rgba(0,0,0,.4)) drop-shadow(0 8px 20px rgba(0,0,0,.26))}
:root[data-theme="light"] .dw-pop .dw-media img{filter:drop-shadow(0 24px 50px rgba(20,15,10,.24))}
.dw-pop:hover .dw-media img{transform:translateY(-6px)}

/* Print roll-up: a SMALL white band pulled up under the billboard so the white covers
   the billboard's stand and the billboard sits directly ON the white (not a floating
   cutout). The banner sits on the far right, tall, rising out of the top toward the billboard. */
.dw-pop{position:relative;z-index:1}
.dw-feature{position:relative;z-index:5;width:100%;max-width:none;
  margin:clamp(-170px,-11vw,-96px) 0 0;
  background:#fff;overflow:visible;
  min-height:clamp(200px,17vw,270px);
  padding:clamp(28px,3.2vw,48px) 0;
  display:flex;align-items:center}
.dw-feat-copy{position:relative;z-index:2;text-align:left;
  margin-left:max(24px,calc(50% - var(--maxw)/2));max-width:38ch}
.dw-feat-copy .fk{display:block;font-family:var(--sans);font-weight:600;font-size:.72rem;
  letter-spacing:.22em;text-transform:uppercase;color:var(--accent);margin-bottom:14px}
.dw-feat-h{font-family:var(--serif);font-weight:800;letter-spacing:-.02em;line-height:1.03;
  font-size:clamp(1.8rem,3.8vw,2.9rem);color:#141311;margin-bottom:14px}
.dw-feat-h .em{font-style:normal;background:linear-gradient(120deg,var(--accent),var(--gold));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}
/* bold subcaption */
.dw-feat-copy p{font-family:var(--sans);font-weight:700;color:#4a453d;letter-spacing:-.005em;
  font-size:clamp(1rem,1.4vw,1.16rem);line-height:1.45;max-width:34ch}
/* banner: base grounded on the white, tall, far right, rising out of the top */
.dw-feature .dw-media{position:absolute;bottom:0;right:clamp(6px,1.6vw,34px);
  margin:0;pointer-events:none;z-index:3;display:block}
.dw-feature .dw-media img{display:block;width:auto;height:clamp(560px,52vw,760px);max-width:none;
  filter:drop-shadow(0 22px 42px rgba(20,15,10,.18));
  transition:transform .6s cubic-bezier(.2,.7,.2,1)}
.dw-feature:hover .dw-media img{transform:translateY(-6px)}

/* ===== desktop composition: banner tall on the LEFT (reaching billboard height) with its
   caption beside it; billboard pushed RIGHT with the "Campaign" caption dropped below it
   onto the white band ===== */
@media(min-width:821px){
  /* 2 · billboard shifts to the right of the stage */
  .dw-pop .dw-media{justify-content:flex-end}
  .dw-pop .dw-media img{margin-right:clamp(24px,6vw,130px)}
  /* 3 · the "Campaign" caption: the original (inside .dw-pop) is hidden on desktop;
     a duplicate inside the white band (.dw-head-desk) sits at the band's TOP-RIGHT,
     directly under the billboard it captions — its own line, clear of the roll-up
     headline no matter the viewport width. */
  .dw-pop{position:static;z-index:auto}
  .dw-pop .dw-head{display:none}
  /* ONE caption for the whole campaign/banner stage: the billboard's "Campaign" label is
     dropped on desktop, leaving only the Print feature copy, centred beside the banner. */
  .dw-head-desk{display:none}
  .dw-feature .dw-media{left:clamp(10px,2.5vw,48px);right:auto;width:auto}
  .dw-feature .dw-media img{height:clamp(620px,56vw,880px)}
  /* the banner file's right half is mostly cast shadow, so the copy can sit well
     inside the image's box and still clear the visible banner. */
  .dw-feat-copy{margin:0 0 0 clamp(170px,16vw,250px);
    max-width:clamp(280px,26vw,400px);text-align:left;z-index:4}
}

@media(max-width:820px){
  .dwork{gap:30px}
  .dw-pop .dw-media img{width:100%}
  /* contained rounded card instead of a full-bleed white slab */
  .dw-feature{margin:clamp(-96px,-18vw,-52px) 14px 0;min-height:0;width:auto;
    flex-direction:column;text-align:center;align-items:center;border-radius:16px;
    padding:clamp(30px,7vw,46px) 20px clamp(24px,6vw,38px)}
  .dw-feat-copy{text-align:center;max-width:none;margin-left:0}
  .dw-feat-copy p{margin:0 auto}
  .dw-feature .dw-media{position:static;margin-top:clamp(18px,4vw,26px);display:flex;justify-content:center;width:100%;right:auto}
  /* portrait banner: size by width so it always fits inside the card.
     The banner artwork sits ~18% left-of-centre inside its own file (the cast shadow
     fills the right half), so nudge the image right by 18% of its width to visually
     centre the actual banner and ignore the shadow. */
  .dw-feature .dw-media img{width:min(78%,300px);height:auto;max-width:100%;transform:translateX(18%)}
  .dw-feature:hover .dw-media img{transform:translateX(18%) translateY(-6px)}
}

/* narrow-phone safety: tighten wide letter-spacing on uppercase eyebrows/labels
   and let them wrap, so no caption gets pushed past the screen edge */
@media(max-width:430px){
  .show-kicker,.mq-cap,.fk,.dw-cat,.sec-num,.eyebrow,.sa-label,.show-lead .show-kicker{
    letter-spacing:.12em;overflow-wrap:break-word}
}

/* ---- story arrow ---- */
.story-arrow{display:flex;flex-direction:column;align-items:center;gap:12px;padding:clamp(18px,3vw,34px) 0}
.sa-label{font-family:var(--sans);font-weight:600;font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;color:var(--accent)}
.sa-svg{width:auto;height:44px;color:var(--faint);animation:saBob 1.9s ease-in-out infinite}
.story-arrow.mini{padding:clamp(4px,1.4vw,14px) 0}
.story-arrow.mini .sa-svg{height:34px}
@keyframes saBob{0%,100%{transform:translateY(0)}50%{transform:translateY(7px)}}
@media(prefers-reduced-motion:reduce){
  .mq-track{animation:none!important}
  .sa-svg{animation:none!important}
}

/* ===== orange→gold gradient on all accent text (matches hero .em) ===== */
.brand span,.nav-cta,.eyebrow,.hero-role b,.crumb span,
.hstat .n span,.irl-stats .n span,.band-cell .n span,
.card-meta .num,.lb-body .num,.tl .yr,.build-body .role,
.show-kicker{
  background:linear-gradient(120deg,var(--accent),var(--gold));
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent}
/* keep the decorative kicker line solid */
.show-kicker::before{-webkit-text-fill-color:initial}

/* ===== bold body captions / sub-text everywhere (headers stay in the serif) ===== */
.hero-desc,.sec-head p,.show p,.show-lead p,.irl-copy p,
.dw-head p,.mq-cap,.cta p{font-weight:700}

/* ===== mobile: tighten oversized section spacing =====
   The desktop section paddings (120px .sec-pad, 100px .cta) leave huge
   empty bands between sections on phones. Scale them down on small screens. */
@media(max-width:760px){
  body.re .sec-pad{padding:60px 0}
  body.re .sec-head{margin-bottom:34px}
  .cta{padding:60px 0}
}
@media(max-width:480px){
  body.re .sec-pad{padding:48px 0}
  body.re .sec-head{margin-bottom:28px}
  .cta{padding:52px 0}
}

/* ============================================================
   LEAD MAGNET — guide.html landing (.lm-*) and the gated
   playbook.php guide itself (.gd-*).
   ============================================================ */

/* ---- landing: two-column offer + sticky form ---- */
.lm{padding:70px 0 30px}
.lm-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:56px;align-items:start}
.lm-copy h2{font-size:var(--fs-h);line-height:var(--lh-h);margin:10px 0 16px}
.lm-lede{color:var(--muted);font-size:1.02rem;max-width:52ch;margin-bottom:30px}
.lm-lede em{color:var(--ink);font-style:italic}

.lm-list{list-style:none;display:grid;gap:22px;margin:0 0 28px}
.lm-list li{display:grid;grid-template-columns:auto 1fr;gap:16px;align-items:start}
.lm-n{font-family:var(--serif);font-weight:700;font-size:.86rem;letter-spacing:.06em;color:var(--accent);
  border:1px solid var(--line);border-radius:8px;padding:7px 9px;line-height:1;background:var(--bg2)}
.lm-list b{font-weight:600;font-size:1.02rem;display:block;margin-bottom:4px}
.lm-list p{color:var(--muted);font-size:.94rem;line-height:1.65}
.lm-who{color:var(--faint);font-size:.9rem;border-top:1px solid var(--line);padding-top:18px}
.lm-who b{color:var(--ink);font-weight:600}

/* ---- the form card ---- */
.lm-form-wrap{position:sticky;top:96px}
.lm-card{background:var(--bg2);border:1px solid var(--line);border-radius:var(--r);padding:28px 26px}
/* The badge pill ("FREE · INSTANT ACCESS"), the tracked-out uppercase field
   labels and the arrow on the button were the three things making this read as
   a generated landing page. All gone: sentence-case labels at normal weight,
   no badge, and the reassurance said ONCE (in the consent line) instead of
   three times in three different registers. */
.lm-card h3{font-size:1.4rem;margin-bottom:6px}
.lm-sub{color:var(--muted);font-size:.92rem;line-height:1.6;margin-bottom:24px}
.lm-lab{display:block;font-size:.86rem;font-weight:500;color:var(--ink);margin:0 0 7px}
.lm-lab span{color:var(--faint);font-weight:400;font-size:.82rem}
.lm-form input[type=text],.lm-form input[type=email]{width:100%;background:var(--bg3);color:var(--ink);
  border:1px solid var(--line);border-radius:10px;padding:13px 15px;font:inherit;font-size:.95rem;
  margin-bottom:16px;transition:border-color .2s,box-shadow .2s}
.lm-form input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(255,77,28,.14)}
.lm-form input::placeholder{color:var(--faint)}
/* honeypot: off-screen for people, still fillable by bots */
.lm-hp{position:absolute!important;left:-9999px!important;width:1px!important;height:1px!important;
  opacity:0!important;pointer-events:none}

.lm-consent{display:grid;grid-template-columns:auto 1fr;gap:10px;align-items:start;
  font-size:.85rem;color:var(--muted);line-height:1.55;margin:6px 0 18px;cursor:pointer}
.lm-consent input{accent-color:var(--accent);width:17px;height:17px;margin-top:2px;cursor:pointer;flex:none}
.lm-btn{width:100%;justify-content:center}
.lm-err{color:var(--accent);font-size:.85rem;margin-top:12px;min-height:1.2em}
.lm-fine{color:var(--faint);font-size:.78rem;line-height:1.6;margin-top:18px;
  border-top:1px solid var(--line);padding-top:16px}
.lm-fine a{color:var(--accent-soft);text-decoration:underline}

.lm-done{text-align:center;padding:8px 0 4px}
.lm-check{width:52px;height:52px;border-radius:50%;background:rgba(255,77,28,.13);color:var(--accent);
  display:grid;place-items:center;margin:0 auto 16px}
.lm-check svg{width:24px;height:24px}
.lm-done h4{font-family:var(--serif);font-size:1.25rem;margin-bottom:8px}
.lm-done-msg{color:var(--muted);font-size:.93rem;margin-bottom:12px}
.lm-done-fine{color:var(--faint);font-size:.8rem;line-height:1.6}

/* ---- the "short version" price table on the landing page ---- */
.lm-peek{padding:60px 0 80px}
.lm-peek h2{font-size:var(--fs-h);line-height:var(--lh-h);margin:10px 0 14px}
.lm-peek>.wrap>p{color:var(--muted);max-width:60ch;margin-bottom:30px}
.lm-tbl{border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:var(--bg2)}
.lm-row{display:grid;grid-template-columns:1fr auto;gap:16px;padding:15px 20px;
  border-bottom:1px solid var(--line2);font-size:.95rem}
.lm-row:last-child{border-bottom:none}
.lm-row span:last-child{font-family:var(--serif);font-weight:700;color:var(--accent);white-space:nowrap}
.lm-head{background:var(--bg3);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--faint)}
.lm-head span:last-child{font-family:var(--sans);font-weight:600;color:var(--faint);letter-spacing:.14em}
.lm-note{color:var(--faint);font-size:.88rem;margin-top:18px;max-width:62ch}

/* ============ THE GUIDE ITSELF (playbook.php) ============ */
.gd{padding:40px 0 90px}
.gd-wrap{max-width:820px}
.gd-sec{margin-bottom:64px}
.gd-num{font-family:var(--serif);font-size:.74rem;letter-spacing:.2em;text-transform:uppercase;color:var(--accent)}
.gd-sec h2{font-size:var(--fs-h);line-height:var(--lh-h);margin:10px 0 16px}
.gd-sec h3{font-size:1.15rem;margin:34px 0 14px}
.gd-sec>p{color:var(--muted);margin-bottom:22px;font-size:1rem}

.gd-tbl{border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:var(--bg2);margin:26px 0}
.gd-row{display:grid;grid-template-columns:1fr auto;gap:18px;padding:16px 20px;border-bottom:1px solid var(--line2)}
.gd-row:last-child{border-bottom:none}
.gd-row b{font-weight:600;display:block;font-size:.97rem}
.gd-row i{font-style:normal;color:var(--faint);font-size:.85rem;display:block;margin-top:3px;line-height:1.5}
.gd-row>span:last-child{font-family:var(--serif);font-weight:700;color:var(--accent);white-space:nowrap;align-self:center}
.gd-head{background:var(--bg3);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--faint)}
.gd-head span:last-child{font-family:var(--sans);font-weight:600;color:var(--faint);letter-spacing:.14em}

.gd-ol{list-style:none;counter-reset:gd;display:grid;gap:18px;margin:0 0 26px}
.gd-ol li{counter-increment:gd;position:relative;padding-left:44px;color:var(--muted);line-height:1.7;font-size:.97rem}
.gd-ol li::before{content:counter(gd);position:absolute;left:0;top:1px;width:29px;height:29px;
  display:grid;place-items:center;border-radius:7px;background:var(--bg3);border:1px solid var(--line);
  font-family:var(--serif);font-weight:700;font-size:.82rem;color:var(--accent)}
.gd-ol b{color:var(--ink);font-weight:600}
.gd-q li span{display:block;margin-top:5px;color:var(--faint);font-size:.9rem}

.gd-call{background:var(--bg2);border:1px solid var(--line);border-left:3px solid var(--accent);
  border-radius:10px;padding:20px 22px;margin:28px 0}
.gd-call b{font-family:var(--serif);font-size:1.02rem;display:block;margin-bottom:7px}
.gd-call p{color:var(--muted);font-size:.94rem;line-height:1.7}

.gd-phase{display:grid;gap:16px;margin:26px 0}
.gd-ph{background:var(--bg2);border:1px solid var(--line);border-radius:var(--r);padding:22px 24px}
.gd-ph-n{font-size:.68rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
.gd-ph h4{font-family:var(--serif);font-size:1.2rem;margin:8px 0 10px;letter-spacing:-.02em}
.gd-ph p{color:var(--muted);font-size:.94rem;line-height:1.7}
.gd-ph-out{margin-top:10px;padding-top:10px;border-top:1px solid var(--line2);font-size:.9rem!important}
.gd-ph-out b{color:var(--ink);font-weight:600}

.gd-end{text-align:center;border-top:1px solid var(--line);padding-top:48px}
.gd-end .cta-btns{justify-content:center;margin-top:24px}
.gd-fine{color:var(--faint);font-size:.82rem;margin-top:26px;line-height:1.7}

@media(max-width:900px){
  .lm-grid{grid-template-columns:1fr;gap:38px}
  .lm-form-wrap{position:static}
}
@media(max-width:560px){
  .lm{padding:50px 0 20px}
  .lm-card{padding:24px 20px}
  .lm-row,.gd-row{grid-template-columns:1fr;gap:6px}
  .lm-row span:last-child,.gd-row>span:last-child{justify-self:start}
  .gd-head span:last-child,.lm-head span:last-child{display:none}
}

/* ============================================================================
   ABOUT PAGE — rebuilt 2026-09-09 on the section architecture of
   magnific.com/company/about-us, rendered in TeniVision's own palette + type.
   What was copied is the COMPOSITION, not the colours:
     · flat ground, no tinted section bands — contrast comes from dark PANELS
       (the stats band, the value cards) punctuating an otherwise plain page
     · ~64-116px between sections, 64px between a section header and its content
     · the eyebrow is MUTED ink, never the accent; headings are flat 800-weight
       with no gradient fill. The accent shows up in exactly three places:
       the story years, the value numbers, and the card icons.
   --panel is a token PAIR so the dark card stays a contrast block in both
   themes: near-black on the cream light theme, a warm raised near-black on
   the dark one (which is why it is #16130f and not #000 — it has to lift off
   a pure-black ground without turning grey).
   ========================================================================= */
:root{--panel:#16130f;--panel-line:rgba(255,255,255,.09);
      --panel-ink:#f4f1ec;--panel-mute:rgba(244,241,236,.66)}
:root[data-theme="light"]{--panel:#141311;--panel-line:rgba(255,255,255,.07)}

.ab-sec{padding:clamp(64px,8.5vw,116px) 0}
.ab-sec.tight{padding-top:0}
.ab-head{max-width:820px;margin-bottom:clamp(34px,4.6vw,64px)}
.ab-head.mid{max-width:none}
.ab-ey{display:block;font-family:var(--sans);font-weight:600;font-size:.72rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);margin-bottom:16px}
.ab-head h2{font-size:var(--fs-h);line-height:var(--lh-h);font-weight:800;letter-spacing:-.025em}
.ab-head p{color:var(--muted);font-size:var(--fs-sub);line-height:var(--lh-sub);margin-top:16px;max-width:62ch}

/* "Meet the full team"-style text link that closes a section */
.ab-more{display:inline-flex;align-items:center;gap:9px;margin-top:30px;font-family:var(--sans);
  font-weight:500;font-size:.98rem;color:var(--ink);border-bottom:1px solid var(--line);
  padding-bottom:4px;transition:.22s}
.ab-more:hover{color:var(--accent);border-bottom-color:var(--accent)}
.ab-more svg{width:15px;height:15px;transition:transform .22s}
.ab-more:hover svg{transform:translateX(4px)}

/* ---- hero: the cine band from the homepage, one column, no capability list -- */
.ab-hero .hero-in{grid-template-columns:minmax(0,1fr);width:min(1160px,74vw)}
.ab-hero h1{font-size:clamp(1.85rem,3.3vw,3.05rem);font-weight:800;line-height:1.05;
  letter-spacing:-.03em;max-width:19ch;margin-bottom:20px;color:#f4f1ec}
.ab-hero .hero-desc{font-size:var(--fs-sub);line-height:var(--lh-sub);max-width:54ch;
  margin-bottom:clamp(26px,3.4vh,36px)}
.ab-hero .crumb{margin-bottom:16px;color:rgba(244,241,236,.5)}
.ab-hero .crumb a{color:rgba(244,241,236,.72)}
.ab-hero .crumb a:hover{color:var(--accent)}
/* THE ABOUT HERO IS CINEMATIC IN BOTH THEMES.
   The reference keeps its about hero as white type on a dark photograph whatever
   else the page does; the light theme's washed scrim turned this into grey type
   on a pale smear. So this hero opts OUT of the light treatment: it always uses
   the dark plate, the dark scrim and light type. Everything below the hero still
   follows the theme normally. */
:root[data-theme="light"] .ab-hero .hero-bg{background:#000}
:root[data-theme="light"] .ab-hero .hero-bg-dark{display:block}
:root[data-theme="light"] .ab-hero .hero-bg-light{display:none}
:root[data-theme="light"] .ab-hero .hero-bg img{mix-blend-mode:screen;opacity:1}
:root[data-theme="light"] .ab-hero .hero-bg::after{
  background:
    linear-gradient(90deg,rgba(0,0,0,.92) 0%,rgba(0,0,0,.8) 34%,rgba(0,0,0,.6) 66%,rgba(0,0,0,.56) 100%),
    linear-gradient(180deg,rgba(0,0,0,.7) 0%,rgba(0,0,0,.1) 22%,rgba(0,0,0,.26) 72%,rgba(0,0,0,.34) 100%)}
:root[data-theme="light"] .ab-hero h1{color:#fff}
:root[data-theme="light"] .ab-hero .hero-desc{color:rgba(255,255,255,.78)}
:root[data-theme="light"] .ab-hero .crumb{color:rgba(255,255,255,.5)}
:root[data-theme="light"] .ab-hero .crumb a{color:rgba(255,255,255,.72)}
/* the nav sits on that dark plate until it scrolls, so keep its ink light too */
:root[data-theme="light"] body.dark-hero header.nav:not(.scrolled):not(.menu-open) .nav-in>.brand,
:root[data-theme="light"] body.dark-hero header.nav:not(.scrolled):not(.menu-open) .nav-links.main>a:not(.nav-cta),
:root[data-theme="light"] body.dark-hero header.nav:not(.scrolled):not(.menu-open) .icon-btn,
:root[data-theme="light"] body.dark-hero header.nav:not(.scrolled):not(.menu-open) .brand b{color:#f4f1ec}
:root[data-theme="light"] body.dark-hero header.nav:not(.scrolled):not(.menu-open) .icon-btn{
  background:rgba(22,19,16,.55);border-color:rgba(255,255,255,.18)}
/* the wordmark is inverted to black in the light theme — undo that over the plate */
:root[data-theme="light"] body.dark-hero header.nav:not(.scrolled):not(.menu-open) .brand .mk-img{filter:none}
:root[data-theme="light"] .ab-hero .btn-hero{background:#f4f1ec;color:#141311}
:root[data-theme="light"] .ab-hero .btn-hero:hover{background:#fff}
@media(max-width:980px){.ab-hero .hero-in{width:100%}}
@media(max-width:640px){
  .ab-hero h1{letter-spacing:-.02em;max-width:none}
}

/* ---- the numbers band: one dark panel holding a header + a 4-up grid ------- */
.ab-nums{background:var(--panel);border:1px solid var(--panel-line);border-radius:16px;
  padding:clamp(28px,4vw,56px);color:var(--panel-ink)}
.ab-nums .ab-head{margin-bottom:clamp(30px,3.6vw,52px)}
.ab-nums .ab-head h2{color:var(--panel-ink)}
.ab-nums .ab-ey,.ab-nums .ab-head p{color:var(--panel-mute)}
.ab-num-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:44px 30px}
.ab-num b{display:block;font-family:var(--serif);font-weight:800;line-height:1;letter-spacing:-.03em;
  font-size:clamp(1.95rem,3.5vw,2.9rem)}
.ab-num span{display:block;margin-top:12px;font-size:.95rem;line-height:1.4;color:var(--panel-mute)}
@media(max-width:760px){.ab-num-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:30px 22px}}

/* ---- card grid: capabilities today, named people whenever you swap them in -- */
/* auto-fill, not repeat(3): the studio is one person today, and a lone card
   stretched across a whole row looks like a layout bug. This keeps every card
   a third-width and simply fills more of the row as people are added. */
.ab-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(288px,1fr));gap:22px}
.ab-card{display:block;color:inherit;position:relative;background:var(--bg2);border:1px solid var(--line);
  border-radius:var(--r);padding:26px;transition:border-color .22s,transform .22s}
.ab-card:hover{border-color:var(--accent);transform:translateY(-2px)}
.ab-card .ic{position:absolute;right:20px;top:22px;width:32px;height:32px;border-radius:8px;
  display:grid;place-items:center;background:var(--bg3);border:1px solid var(--line2);color:var(--accent)}
.ab-card .ic svg{width:16px;height:16px}
.ab-card h3{font-family:var(--sans);font-weight:500;font-size:1.06rem;letter-spacing:-.01em;
  line-height:1.35;padding-right:46px}
.ab-card .role{margin-top:5px;font-size:.97rem;color:var(--muted)}
.ab-card p{margin-top:13px;font-size:.94rem;line-height:1.65;color:var(--muted)}
@media(max-width:600px){.ab-cards{grid-template-columns:1fr}}

/* ---- story: a hairline the rows hang off, year in the accent -------------- */
.ab-story-row{position:relative;display:grid;grid-template-columns:170px minmax(0,1fr);gap:32px;
  border-left:1px solid var(--line);padding:0 0 clamp(32px,4vw,52px) 32px}
.ab-story-row:last-child{padding-bottom:0;border-left-color:transparent}
.ab-story-row::before{content:"";position:absolute;left:-4px;top:10px;width:7px;height:7px;
  border-radius:50%;background:var(--accent)}
.ab-story-row .yr{font-family:var(--serif);font-weight:800;line-height:1.05;letter-spacing:-.02em;
  font-size:clamp(1.3rem,2.15vw,1.68rem);color:var(--accent)}
.ab-story-row h3{font-size:clamp(1.08rem,1.65vw,1.3rem);font-weight:800;letter-spacing:-.02em;line-height:1.2}
.ab-story-row p{margin-top:10px;color:var(--muted);font-size:1.02rem;line-height:1.65;max-width:62ch}
@media(max-width:760px){
  .ab-story-row{grid-template-columns:1fr;gap:10px;padding-left:24px}
  .ab-story-row::before{top:8px}
}

/* ---- values: 2x2 dark panels, big accent numeral ------------------------- */
.ab-vals{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.ab-val{background:var(--panel);border:1px solid var(--panel-line);border-radius:16px;
  padding:clamp(26px,3vw,36px);color:var(--panel-ink)}
.ab-val .n{font-family:var(--serif);font-weight:800;line-height:1;letter-spacing:-.03em;
  font-size:clamp(1.9rem,3vw,2.4rem);color:var(--accent)}
.ab-val h3{margin-top:clamp(20px,2.6vw,28px);font-size:clamp(1.15rem,1.8vw,1.45rem);font-weight:800;
  letter-spacing:-.02em;line-height:1.15}
.ab-val p{margin-top:12px;font-size:.98rem;line-height:1.7;color:var(--panel-mute)}
@media(max-width:760px){.ab-vals{grid-template-columns:1fr}}

/* ---- what we make: two columns of hairline link rows ---------------------- */
.ab-make{display:grid;grid-template-columns:1fr 1fr;gap:0 46px}
.ab-make a{display:flex;align-items:center;justify-content:space-between;gap:18px;
  padding:19px 2px;border-bottom:1px solid var(--line);transition:color .22s}
.ab-make a b{display:block;font-family:var(--serif);font-weight:700;letter-spacing:-.02em;
  line-height:1.2;font-size:clamp(.98rem,1.4vw,1.14rem)}
.ab-make a i{display:block;margin-top:5px;font-style:normal;font-family:var(--sans);
  font-weight:400;font-size:.9rem;line-height:1.5;color:var(--muted)}
.ab-make a svg{width:17px;height:17px;flex:0 0 auto;color:var(--faint);transition:.22s}
.ab-make a:hover{color:var(--accent)}
.ab-make a:hover svg{color:var(--accent);transform:translateX(4px)}
@media(max-width:700px){.ab-make{grid-template-columns:1fr}}

/* ---- careers call-out ---------------------------------------------------- */
.ab-pill{display:inline-flex;align-items:center;height:26px;padding:0 12px;border-radius:6px;
  border:1px solid var(--line);font-family:var(--sans);font-weight:500;font-size:.75rem;
  color:var(--muted);margin-bottom:18px}
.ab-join h2{font-size:var(--fs-h);line-height:var(--lh-h);font-weight:800;letter-spacing:-.025em}
.ab-join p{color:var(--muted);font-size:var(--fs-sub);line-height:var(--lh-sub);margin:16px 0 30px;max-width:56ch}

/* ---- contact: three cards, the address pinned to the bottom-right --------- */
.ab-contact-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:22px}
.ab-cc{display:flex;flex-direction:column;min-height:184px;background:var(--bg2);
  border:1px solid var(--line);border-radius:var(--r);padding:26px;
  transition:border-color .22s,transform .22s}
.ab-cc:hover{border-color:var(--accent);transform:translateY(-2px)}
.ab-cc h3{font-family:var(--sans);font-weight:500;font-size:1.06rem;letter-spacing:-.01em}
.ab-cc p{margin-top:9px;color:var(--muted);font-size:.96rem;line-height:1.6}
.ab-cc .addr{margin-top:auto;padding-top:22px;text-align:right;font-weight:600;font-size:.95rem;
  color:var(--ink);word-break:break-word}
.ab-cc:hover .addr{color:var(--accent)}
@media(max-width:820px){.ab-contact-grid{grid-template-columns:1fr}}


/* ---- brand proof cards ----------------------------------------------------
   The reference backs each card with an out-of-focus photograph in the client's
   colour, logo top-left, copy at the foot. Ours are generated washes in each
   brand's own sampled colour (scripts/make-brand-cards.php) — the logo art is
   the same white mono tile the homepage strip uses, so nothing new was drawn.
   Cards are dark in BOTH themes: the background is an image, so the white logo
   and white copy have to stay white. `.qt`/`.by` are the quote slot — empty
   until a real quote is written in the admin. */
.ab-brands{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:22px}
.ab-brands>.ab-brand:first-child{grid-column:span 2}
.ab-brand{position:relative;isolation:isolate;overflow:hidden;display:flex;flex-direction:column;
  min-height:326px;padding:clamp(22px,2.4vw,30px);border-radius:16px;
  border:1px solid rgba(255,255,255,.1);color:#f4f1ec}
.ab-brand .bg{position:absolute;inset:0;z-index:-1;width:100%;height:100%;object-fit:cover}
.ab-brand .lg{align-self:flex-start;width:clamp(118px,40%,164px);height:auto;object-fit:contain}
.ab-brand .bd{margin-top:auto;padding-top:30px}
.ab-brand .did{font-size:1rem;line-height:1.55;color:rgba(244,241,236,.9)}
.ab-brand .qt{font-size:1.04rem;line-height:1.55}
.ab-brand .by{margin-top:14px;font-size:.85rem;font-weight:500;color:rgba(244,241,236,.68)}
.ab-brand .qt+.did{margin-top:14px;font-size:.88rem;color:rgba(244,241,236,.62)}
@media(max-width:1040px){
  .ab-brands{grid-template-columns:1fr 1fr}
  .ab-brands>.ab-brand:first-child{grid-column:span 2}
}
@media(max-width:700px){
  .ab-brands{grid-template-columns:1fr}
  .ab-brands>.ab-brand:first-child{grid-column:auto}
  .ab-brand{min-height:256px}
}

/* ---- phones: the numbers panel needed its own balance ----------------------
   At the shared sizes the heading ran to four lines and the two figures nearly
   touched — 2.3rem of Syne in a ~124px column leaves almost no gutter. Panel
   padding, heading and figures all come down together so the block reads as one
   calm card instead of a cramped one. */
@media(max-width:640px){
  .ab-nums{padding:26px 20px;border-radius:14px}
  .ab-nums .ab-head{margin-bottom:26px}
  .ab-nums .ab-head h2{font-size:min(6.7vw,1.68rem);letter-spacing:-.02em;line-height:1.08}
  .ab-nums .ab-head p{margin-top:12px}
  .ab-num-grid{gap:24px 16px}
  .ab-num b{font-size:min(10.5vw,2.2rem)}
  .ab-num span{margin-top:8px;font-size:.86rem;line-height:1.35}
}

/* ---- people card: an optional portrait above the name ---------------------
   Set meta.photo in admin to a path WITHOUT the size suffix
   (works/team/felix-oladimeji) — app.js derives the -160/-320 srcset pair.
   Cards without a photo are unchanged, so a capability row still looks right. */
.ab-card .pic{display:block;width:72px;height:72px;border-radius:50%;object-fit:cover;
  margin-bottom:16px;border:1px solid var(--line);background:var(--bg3)}
@media(max-width:600px){.ab-card .pic{width:64px;height:64px;margin-bottom:14px}}

/* privacy page: the analytics opt-out that backs the notice-only cookie bar */
.pv-optout{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin:18px 0 6px}
.pv-optout-msg{font-size:.88rem;color:var(--muted)}

/* ---- "Want to join the team?" card ---------------------------------------
   Sits in the people grid but must not read as a person: no portrait, a dashed
   edge, and the icon chip carries an arrow rather than a mark. Links to
   careers.html, which already lists the open roles. */
.ab-card-join{border-style:dashed;background:transparent}
.ab-card-join:hover{background:var(--bg2);border-style:solid}
.ab-card-join .ic{color:var(--muted);background:transparent}
.ab-card-join:hover .ic{color:var(--accent)}
.ab-card-cta{display:inline-flex;align-items:center;gap:8px;margin-top:16px;
  font-family:var(--sans);font-weight:500;font-size:.92rem;color:var(--ink);transition:color .22s}
.ab-card-cta svg{width:14px;height:14px;transition:transform .22s}
.ab-card-join:hover .ab-card-cta{color:var(--accent)}
.ab-card-join:hover .ab-card-cta svg{transform:translateX(4px)}

/* ---- inner-page header plate --------------------------------------------
   Every inner page now sits its header on an abstract, out-of-focus plate
   generated per page by scripts/make-page-headers.php (mode + hue chosen to
   relate to the page). Same deal as the About hero: the plate is DARK in both
   themes and the type on it is always light, so this opts out of the light
   theme rather than following it. `body.dark-hero` (set in tvHero) is what
   keeps the nav's ink light over it.
   The header is LEFT-aligned here — centred type over a directional plate
   fought the art, and the reference is left-aligned too. */
.page-hero.hero-img{text-align:left;padding:clamp(112px,13vh,150px) 0 clamp(52px,7vh,78px)}
.page-hero.hero-img .wrap{position:relative}
.page-hero.hero-img .hero-bg{background:#000}
.page-hero.hero-img .hero-bg img{width:100%;height:100%;object-fit:cover;object-position:center}
.page-hero.hero-img .hero-bg::after{content:"";position:absolute;inset:0;
  background:
    linear-gradient(90deg,rgba(0,0,0,.86) 0%,rgba(0,0,0,.7) 38%,rgba(0,0,0,.42) 72%,rgba(0,0,0,.38) 100%),
    linear-gradient(180deg,rgba(0,0,0,.6) 0%,rgba(0,0,0,.12) 26%,rgba(0,0,0,.26) 74%,rgba(0,0,0,.34) 100%)}
/* NO `var(--bg)` STOP ON THIS ONE. The plate is dark in both themes, so fading
   its last stop into the ground painted a bright WHITE WASH across the bottom of
   every light-theme header — it read as a glow sitting under the copy. The
   reference doesn't fade either: its header image just ends on a clean edge. */
.page-hero.hero-img h1{color:#f4f1ec;max-width:18ch}
.page-hero.hero-img p{color:rgba(255,255,255,.76);margin-left:0;margin-right:0;max-width:56ch}
.page-hero.hero-img .crumb{color:rgba(255,255,255,.5)}
.page-hero.hero-img .crumb a{color:rgba(255,255,255,.72)}
.page-hero.hero-img .crumb a:hover,.page-hero.hero-img .crumb span{color:var(--accent)}
.page-hero.hero-img .eyebrow{color:rgba(255,255,255,.62)}
/* the plate is dark whatever the theme, so the light theme must not re-tint it */
:root[data-theme="light"] .page-hero.hero-img h1{color:#fff}
:root[data-theme="light"] .page-hero.hero-img p{color:rgba(255,255,255,.78)}
@media(max-width:760px){
  .page-hero.hero-img{padding:clamp(88px,12vh,104px) 0 clamp(34px,5vh,48px)}
  .page-hero.hero-img h1{max-width:none}
}

/* ---- LANGUAGE PICKER ------------------------------------------------------
   Our control, Google's translation. Styled off the reference: a bordered pill
   in the nav that opens a panel with a search field and a scrolling list.
   Marked translate="no" in the markup so Google leaves the language names
   alone — "Deutsch" must read Deutsch in every locale. */
.tv-lang{position:relative;display:flex;align-items:center}
.tv-lang-btn{display:inline-flex;align-items:center;gap:7px;height:38px;padding:0 11px;
  border-radius:8px;border:1px solid var(--line);background:transparent;color:var(--ink);
  font-family:var(--sans);font-weight:500;font-size:.8rem;cursor:pointer;
  transition:border-color .2s,background .2s}
.tv-lang-btn:hover{border-color:var(--ink)}
.tv-lang-btn svg{width:15px;height:15px;flex:0 0 auto}
.tv-lang-chev{width:13px;height:13px;opacity:.6;transition:transform .22s}
.tv-lang.open .tv-lang-chev{transform:rotate(180deg)}
/* translating: the chevron becomes a small spinner */
.tv-lang.busy .tv-lang-chev{opacity:1;border-radius:50%;border:2px solid currentColor;border-right-color:transparent;
  box-sizing:border-box;animation:tvLangSpin .7s linear infinite}
.tv-lang.busy .tv-lang-chev path{display:none}
@keyframes tvLangSpin{to{transform:rotate(360deg)}}
.tv-lang-cur{max-width:9ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* over a dark hero plate the nav ink is light, so the pill has to follow */
body.dark-hero header.nav:not(.scrolled):not(.menu-open) .tv-lang-btn{color:#f4f1ec;border-color:rgba(255,255,255,.22)}
body.dark-hero header.nav:not(.scrolled):not(.menu-open) .tv-lang-btn:hover{border-color:#f4f1ec}

.tv-lang-panel{position:absolute;top:calc(100% + 10px);right:0;z-index:60;
  width:min(300px,calc(100vw - 32px));padding:10px;border-radius:12px;
  background:var(--bg2);border:1px solid var(--line);
  box-shadow:0 26px 60px -22px rgba(0,0,0,.55)}
.tv-lang-search{display:flex;align-items:center;gap:9px;padding:0 11px;margin-bottom:8px;
  border-radius:8px;border:1px solid var(--line);background:var(--bg)}
.tv-lang-search svg{width:15px;height:15px;flex:0 0 auto;color:var(--faint)}
.tv-lang-search input{flex:1;min-width:0;padding:11px 0;border:0;background:none;color:var(--ink);
  font-family:var(--sans);font-size:.86rem}
.tv-lang-search input:focus{outline:none}
.tv-lang-search input::placeholder{color:var(--faint)}
.tv-lang-list{max-height:270px;overflow-y:auto;overscroll-behavior:contain;
  display:flex;flex-direction:column;gap:1px;scrollbar-width:thin}
.tv-lang-list button{display:block;width:100%;text-align:left;padding:10px 11px;border:0;
  border-radius:6px;background:none;color:var(--ink);cursor:pointer;
  font-family:var(--sans);font-weight:400;font-size:.9rem;transition:background .15s}
.tv-lang-list button:hover{background:var(--bg3)}
.tv-lang-list button.on{color:var(--accent);font-weight:600}
.tv-lang-list button small{margin-left:8px;font-size:.76rem;color:var(--faint);font-weight:400}
.tv-lang-list button.kb{background:var(--bg3)}
.tv-lang-list button:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
/* the buttons are display:block, which beat the [hidden] attribute — so the
   search hid nothing and looked broken. Hidden has to win. */
.tv-lang-list [hidden]{display:none!important}
.tv-lang-empty{margin:0;padding:14px 11px;font-size:.86rem;color:var(--faint)}
@media(max-width:860px){
  .tv-lang-cur{display:none}
  .tv-lang-btn{padding:0 9px;gap:5px}
  /* The button sits ~110px in from the right edge here, so a 300px panel pinned
     to its right side ran off the LEFT of the screen. Un-position the wrapper so
     the panel anchors to the fixed header bar instead, and span the bar's width
     with a 12px margin either side. */
  .tv-lang{position:static}
  /* ...but the icon cluster itself was still position:relative (left over from the
     old full-screen menu), so the panel anchored to that ~100px cluster and got
     squeezed into a sliver. Let it fall through to the fixed header bar. */
  .nav-in>.nav-links:not(.main){position:static}
  .tv-lang-panel{left:12px;right:12px;width:auto;top:calc(100% + 6px)}
  .tv-lang-list{max-height:min(270px,calc(100dvh - 190px))}
  /* under 16px iOS zooms the whole page into the field the moment it's tapped */
  .tv-lang-search input{font-size:16px}
}

/* ---- Google Translate chrome we do not want -------------------------------
   The embed injects a banner iframe that shifts the whole document down by
   ~40px (it sets body{top}), a hover tooltip, and a highlight background on
   every translated run. All of it is suppressed; the hidden host element is
   what Google actually renders its widget into. */
#tvGtHost{display:none}
/* `iframe.skiptranslate` is the catch-all. Google shipped a NEW banner whose
   class is generated (VIpgJd-ZVi9od-ORHb-OEVmcd), so targeting the legacy
   .goog-te-banner-frame alone left a bar across the top that pushed the nav
   down. Every iframe the widget injects is chrome, never content. */
iframe.skiptranslate,.goog-te-banner-frame,.goog-te-gadget-icon,
#goog-gt-tt,.goog-tooltip,.goog-tooltip:hover{display:none!important}
body{top:0!important}
.goog-text-highlight{background:none!important;box-shadow:none!important}

/* ---- closing CTA band ------------------------------------------------------
   The reference closes every page with a full-bleed image strip carrying one
   line and one button. Same here, on the shared abstract plate. Dark in both
   themes, so the type is fixed light rather than themed. */
.cta.cta-img{position:relative;isolation:isolate;overflow:hidden;text-align:center;
  padding:clamp(76px,9vw,120px) 0;color:#f4f1ec}
.cta-bg{position:absolute;inset:0;z-index:-1;overflow:hidden;background:#000}
.cta-bg img{width:100%;height:100%;object-fit:cover;object-position:center}
.cta-bg::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(0,0,0,.52) 0%,rgba(0,0,0,.3) 45%,rgba(0,0,0,.62) 100%)}
.cta.cta-img h2{color:#f4f1ec}
.cta.cta-img p{color:rgba(255,255,255,.8)}
.cta.cta-img .sec-num,.cta.cta-img .eyebrow{color:rgba(255,255,255,.62)}
.cta.cta-img .btn-ghost{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.28);color:#f4f1ec}
.cta.cta-img .btn-ghost:hover{background:rgba(255,255,255,.16);border-color:#f4f1ec}
:root[data-theme="light"] .cta.cta-img h2{color:#f4f1ec}
:root[data-theme="light"] .cta.cta-img p{color:rgba(255,255,255,.8)}

/* ---- the footer does NOT follow the theme --------------------------------
   Client's call: it stays dark on both. Rather than restating every colour,
   the footer REDEFINES the theme tokens on itself — custom properties cascade,
   so every var(--ink)/var(--muted)/var(--line) inside it resolves dark without
   touching a single component rule. The one thing tokens cannot fix is the
   wordmark, which the light theme inverts to black: un-invert it here. */
:root[data-theme="light"] footer.megafoot,
:root[data-theme="light"] footer{
  --bg:#000; --bg2:#0a0a0c; --bg3:#141417;
  --ink:#f4f1ec; --muted:#9a958d; --faint:#6b6862;
  --line:rgba(255,255,255,.09); --line2:rgba(255,255,255,.06);
  --band:#0a0a0c;
  background:#0a0a0c;color:#f4f1ec;border-top-color:rgba(255,255,255,.09)}
:root[data-theme="light"] footer .brand .mk-img{filter:none}
:root[data-theme="light"] footer .brand b{color:#f4f1ec}
