@font-face{font-family:'Sprat';src:url('fonts/Sprat-Thin.woff2') format('woff2');font-weight:100;font-style:normal;font-display:swap}
@font-face{font-family:'Sprat';src:url('fonts/Sprat-Regular.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Sprat';src:url('fonts/Sprat-Medium.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'Sprat';src:url('fonts/Sprat-Bold.woff2') format('woff2');font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:'Sprat';src:url('fonts/Sprat-Black.woff2') format('woff2');font-weight:800;font-style:normal;font-display:swap}

:root{
  --fg:#0D99FF;          /* accent */
  --c0:#0B0B0C;          /* app chrome background */
  --c1:#1E1E1E;          /* panel background */
  --c2:#2C2C2C;          /* panel hover */
  --c3:#383838;          /* panel active / borders */
  --line:#2E2E2E;
  --tx:#FFFFFF;
  --t2:#B3B3B3;
  --t3:#808080;
  --desk:#E9E9E9;        /* canvas desk background */
  --ink:#1A1A1E;         /* page ink (light case) */
  --dim:#5C5C66;
  --wline:#E7E7EA;
  --soft:#F5F5F7;
}

/* Reading progress — a thin bar above the whole app chrome that fills as you
   scroll through a case study's frames, the way the reference portfolio's
   does. Only shown while a case is open; About and the rest of the site
   don't have "sections to scroll through" in the same sense. */
/* Sits inside the canvas, pinned just under the ruler and above the first
   frame — in the empty strip .canvas-inner leaves above frame 00, not
   floating over the whole viewport. */
.scroll-progress{position:absolute;top:23px;left:23px;right:0;height:3px;z-index:6;opacity:0;transition:opacity .2s ease;pointer-events:none;background:transparent}
.scroll-progress.on{opacity:1}
.scroll-progress-fill{height:100%;width:0%;background:var(--fg,#0D99FF)}

*{box-sizing:border-box}
html,body{height:100%;margin:0;padding:0}
body{
  font-family:'Space Grotesk',system-ui,-apple-system,sans-serif;
  background:var(--c0);
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4,h5,h6{font-family:'Sprat','Space Grotesk',sans-serif}
a{color:var(--fg);text-decoration:none}
a:hover{color:#3AAEFF}
img{max-width:100%;display:block}
::selection{background:var(--fg);color:#fff}
::-webkit-scrollbar{width:12px;height:12px}
::-webkit-scrollbar-thumb{background:rgba(140,140,150,.4);border-radius:8px;border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-track{background:transparent}

/* ===== Case detail dark palette (applied only to .canvas-inner while viewing the Agentic Search case) ===== */
.canvas-inner.case-dark{
  --ink:#FFFFFF;
  --dim:#9B9BA6;
  --wline:#22222A;
  --soft:#15151B;
}

/* ===== Case detail warm palette (applied only to .canvas-inner while viewing the Survey Builder case) ===== */
.canvas-inner.case-warm{
  --ink:#181310;
  --dim:#8C8171;
  --wline:#E6DDC7;
  --soft:#F5F0E4;
  --fg:#C2571C;
}
.canvas-wrap.case-fullbleed .canvas:has(.canvas-inner.case-warm){background:#F5F0E4}

/* ===== Case detail Haus palette (applied only to .canvas-inner while viewing the Haus Hotel case) ===== */
.canvas-inner.case-haus{
  --ink:#17223B;
  --dim:#5B6478;
  --wline:#E4DCC4;
  --soft:#FAF6EC;
  --fg:#C98A1C;
}
.canvas-wrap.case-fullbleed .canvas:has(.canvas-inner.case-haus){background:#FAF6EC}

/* Widen the text containers throughout the Haus case study (left-aligned, just not clipped to the narrow default max-width) */
.canvas-inner.case-haus .case-title,
.canvas-inner.case-haus .case-sub,
.canvas-inner.case-haus .case-section h2,
.canvas-inner.case-haus .case-section p,
.canvas-inner.case-haus .case-quote{max-width:none}

/* Haus: the shared .accent eyebrow defaults to the dark case's coral — re-theme to gold */
.canvas-inner.case-haus .case-eyebrow.accent{color:#B07C14;font-weight:700}
.canvas-inner.case-haus .case-eyebrow .bar{background:#C98A1C}
.canvas-inner.case-haus .case-quote{
  border-left:3px solid #C98A1C;
  background:#FBF6E9;
  color:#4A3A15;
  font-size:20px;
  font-style:italic;
  font-weight:500;
}

/* ===== Case detail Cockpit palette (Shippeo Voyager 3) ===== */
.canvas-inner.case-cockpit{
  --ink:#0A1E42;
  --dim:#6B7280;
  --wline:#E5E7EB;
  --soft:#F9FAFB;
  --fg:#3873E1;
}
.canvas-wrap.case-fullbleed .canvas:has(.canvas-inner.case-cockpit){background:#FBFCFE}
.canvas-inner.case-cockpit .case-title,
.canvas-inner.case-cockpit .case-sub,
.canvas-inner.case-cockpit .case-section h2,
.canvas-inner.case-cockpit .case-section p,
.canvas-inner.case-cockpit .case-quote{max-width:none}

/* Cockpit used to override the case title into Voyager 3's own Roboto/900
   system so the heading read like the product. Every case title now shares
   the same editorial serif as the Home hero instead, so only the measure
   (a full-sentence heading needs its own max-width or it runs the width of
   the sheet) and colour survive the override. */
.canvas-inner.case-cockpit .case-title{
  color:#0A1E42;
  max-width:920px;
}
.canvas-inner.case-cockpit .case-section h2{
  font-family:'Roboto','Space Grotesk',sans-serif;
  font-weight:700;
  font-size:28px;
  letter-spacing:-.018em;
  line-height:1.28;
  color:#0A1E42;
  margin-top:14px;
}
.canvas-inner.case-cockpit .case-eyebrow{
  font-family:'Roboto','Space Grotesk',sans-serif;
  font-size:12px;
  font-weight:700;
  letter-spacing:.085em;
  text-transform:uppercase;
  color:#6B7280;
}
.canvas-inner.case-cockpit .case-eyebrow .bar{width:16px;height:2px;border-radius:2px}
.canvas-inner.case-cockpit .case-sub,
.canvas-inner.case-cockpit .case-section p,
.canvas-inner.case-cockpit .case-facts .k,
.canvas-inner.case-cockpit .case-facts .v{font-family:'Roboto','Space Grotesk',sans-serif}
.canvas-inner.case-cockpit .case-section p{font-size:16px;line-height:1.72;color:#374151}
.canvas-inner.case-cockpit .case-sub{font-size:16px;line-height:1.68;color:#6B7280}
.canvas-inner.case-cockpit .case-tag{font-family:'Roboto','Space Grotesk',sans-serif;font-weight:700}

/* Cockpit: re-theme the shared case components (built for the dark case) onto Voyager 3.
   Literal hex rather than var() so these always beat the dark-case defaults. */
.canvas-inner.case-cockpit .case-eyebrow.accent{color:#3873E1;font-weight:700}
.canvas-inner.case-cockpit .case-eyebrow .bar{background:#3873E1}
.canvas-inner.case-cockpit .case-quote{
  border-left:3px solid #3873E1;
  background:#F2F6FE;
  color:#11326F;
  font-size:16px;
  font-weight:600;
  border-radius:0 12px 12px 0;
}
.canvas-inner.case-cockpit .problem-box{
  background:#FFFFFF;
  border:1px solid #E5E7EB;
  border-radius:14px;
  box-shadow:0 1px 2px rgba(10,30,66,.04);
}
.canvas-inner.case-cockpit .problem-box-label{
  font-family:'Roboto','Space Grotesk',sans-serif;
  font-size:12px;font-weight:700;color:#6B7280;letter-spacing:.085em;
}
.canvas-inner.case-cockpit .problem-step{
  background:#F9FAFB;
  border:1px solid #E5E7EB;
  align-items:flex-start;
}
.canvas-inner.case-cockpit .problem-step .num{
  background:#E9EFFC;
  color:#1E59C7;
  font-family:ui-monospace,'Roboto Mono',monospace;
  font-size:12px;
  margin-top:1px;
}
.canvas-inner.case-cockpit .problem-step .title{font-family:'Roboto','Space Grotesk',sans-serif;font-size:16px;font-weight:700;color:#0A1E42}
.canvas-inner.case-cockpit .problem-step .sub{font-family:'Roboto','Space Grotesk',sans-serif;color:#6B7280;font-size:14px;line-height:1.55}
.canvas-inner.case-cockpit .problem-step.warn{background:#FEF2F2;border:1px solid #FCA5A5}
.canvas-inner.case-cockpit .problem-step.warn .num{background:#EF4444;color:#FFFFFF}
.canvas-inner.case-cockpit .problem-step.warn .title{color:#991B1B}
.canvas-inner.case-cockpit .problem-step.warn .sub{color:#B4534E}
.canvas-inner.case-cockpit .stat-strip .stat{background:#FFFFFF;border:1px solid #E5E7EB;border-radius:12px}
.canvas-inner.case-cockpit .stat-strip .stat .n{color:#3873E1}
.canvas-inner.case-cockpit .stat-strip .stat .t{color:#0A1E42}
.canvas-inner.case-cockpit .stat-strip .stat .d{color:#6B7280}

@keyframes fadeUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes wave{0%,60%,100%{transform:rotate(0)}10%{transform:rotate(14deg)}20%{transform:rotate(-8deg)}30%{transform:rotate(14deg)}40%{transform:rotate(-4deg)}50%{transform:rotate(10deg)}}
@keyframes floaty{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}}
@keyframes pillIn{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}
@keyframes shimmer{to{background-position:200% center}}
@keyframes marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@keyframes figblink{0%,50%{opacity:1}50.01%,100%{opacity:0}}

/* ============================================================
   Shell layout
   ============================================================ */
#shell{display:flex;flex-direction:column;height:100vh;min-width:1180px;overflow:hidden;background:var(--c0)}

/* ---- Chrome bar ---- */
.chrome-bar{
  position:relative;   /* the tab-search panel hangs off this */
  display:flex;align-items:center;gap:14px;height:42px;padding:0 14px;flex:none;
  background:#333336;border-bottom:1px solid #262629;
}
.traffic-lights{display:flex;gap:8px;flex:none}
.traffic-lights{align-items:center}
.tl{width:12px;height:12px;border-radius:50%;flex:none}
.tl.red{background:#FF5F57}.tl.yellow{background:#FEBC2E}.tl.green{background:#28C840}
/* One box, one icon size, one stroke weight for every control in the bar, so
   they sit on the same line and carry the same visual weight. The glyphs are
   drawn centred in a 24 viewBox (the old house spanned 3..20, which made it
   ride high next to the traffic lights), and the + is an icon rather than a
   text character — as a glyph it sat on a baseline and read thin beside the
   1.8-weight strokes either side of it. */
.chrome-icon{
  width:28px;height:28px;border-radius:6px;flex:none;
  display:flex;align-items:center;justify-content:center;
  color:#C9C9CF;background:none;border:0;padding:0;cursor:pointer;
}
.chrome-icon svg{width:17px;height:17px;display:block}
.chrome-icon:hover{background:#42424699}
/* The tab is the same 28px box as the icon buttons either side of it, so it
   sits on the same centre line rather than being anchored to the bottom edge
   of the bar. Bottom-anchoring is the browser-tab metaphor, but here the tab
   strip and the icon row are one 42px row, which left the tab 7.5px low
   against every icon. Centred, it needs a radius on all four corners. */
.chrome-tab{
  display:flex;align-items:center;gap:9px;height:28px;padding:0 12px;border-radius:7px;
  background:#1E1E1E;color:#EDEDF0;font-size:12px;font-weight:500;align-self:center;
  cursor:pointer;
}
.chrome-tab.tab-inactive{background:transparent;color:#9C9CA4}
.chrome-tab.tab-inactive:hover{background:#3B3B3F80}
.tab-icon{width:14px;height:14px;flex:none;display:inline-flex;align-items:center;justify-content:center}
.tab-close{margin-left:4px;color:#8A8A92;cursor:pointer}
.tab-close:hover{color:#EDEDF0}
/* Holds one .chrome-tab per open file, Figma-style — grows as more cases are
   opened and scrolls sideways rather than squeezing the rest of the bar once
   it runs out of room. */
/* No open tabs (a fresh Home load, or every tab closed) left this as an
   empty flex item — invisible, but the bar's own 14px gap still applied on
   both sides of it, doubling up into a 28px gap between the home icon and
   the + button. Dropping it from the layout when empty collapses that back
   to one normal 14px gap. */
.chrome-tabs:empty{display:none}
.chrome-tabs{display:flex;align-items:center;gap:6px;min-width:0;overflow-x:auto;scrollbar-width:none}
.chrome-tabs::-webkit-scrollbar{display:none}
.chrome-tabs .chrome-tab{flex:none;max-width:190px}
.chrome-tabs .tab-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chrome-spacer{flex:1}

/* Mobile-only "Connect" button in the chrome bar — see the media query below
   for the display:flex + flex `order` that actually places it; hidden here
   so desktop, which already has "Let's Connect" in the inspector, keeps its
   chrome bar unchanged. */
.chrome-connect-wrap{display:none}
/* Same story: enhanceCaseImagesMobile() appends these unconditionally once a
   phone-width session has created them, and never removes them again on a
   resize back to desktop — this default (which the mobile media query below
   overrides) is what actually hides them again at desktop widths. Declared
   before that media query so the override wins the cascade once it applies. */
.expand-badge{display:none}
.chrome-connect-btn{
  height:28px;padding:0 12px;border-radius:7px;border:0;flex:none;
  background:var(--fg,#0D99FF);color:#fff;font-size:12px;font-weight:600;
  font-family:inherit;white-space:nowrap;cursor:pointer;
  display:inline-flex;align-items:center;
}
.chrome-connect-btn:hover{background:#0B87E3}

/* ---- tab search, anchored to the bar ---- */
.tab-search{
  position:absolute;top:40px;right:10px;width:342px;z-index:60;
  background:#1E1E1E;border:1px solid #303034;border-radius:12px;
  box-shadow:0 20px 50px rgba(0,0,0,.55);padding:10px;
  color:#EDEDF0;font-size:13px;
}
.ts-field{
  display:flex;align-items:center;gap:9px;padding:9px 11px;
  border-radius:9px;background:#141416;border:1.5px solid var(--fg);color:#8A8A92;
}
.ts-field input{
  flex:1;min-width:0;background:none;border:0;outline:none;
  color:#EDEDF0;font-size:13px;font-family:inherit;
}
.ts-field input::placeholder{color:#8A8A92}
.ts-kbd{font-size:11.5px;color:#8A8A92;flex:none}
.ts-list{max-height:min(60vh,420px);overflow-y:auto;margin-top:6px}
.ts-group{padding-top:6px}
.ts-group-head{font-size:12px;color:#9C9CA4;padding:8px 9px 4px}
.ts-row{
  display:flex;align-items:center;gap:11px;
  padding:8px 9px;border-radius:8px;cursor:pointer;
  color:#EDEDF0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.ts-row svg{flex:none}
.ts-row:hover{background:#2F3346}
.ts-empty{padding:14px 9px;color:#8A8A92}

/* ---- Body row ---- */
/* ==========================================================================
   Type scale — aligned to Material Design 3's steps, restricted to the sizes
   we actually use: 12 / 14 / 16 / 20 / 24 / 28 / 32 / 48 / 58 / 64.
   Every font-size in this file sits on one of these. Nothing goes below 12px.

     --fs-label     12   Material Label Medium  — uppercase eyebrows, badges, meta
     --fs-body-sm   14   Material Body Medium   — supporting text in dense UI
     --fs-body      16   Material Body Large    — descriptions and body copy
     --fs-title     20   Material Title Large   — card titles, section labels
     --fs-h3        24   Material Headline Small
     --fs-h2        28   Material Headline Medium
     --fs-h1        32   Material Headline Large
     --fs-display   48   Material Display Small
     --fs-display-l 58   Material Display Medium
     --fs-display-x 64   Material Display Large

   The one deliberate exception is the canvas ruler numerals, which are
   decorative and have to fit inside a 23px strip.
   ========================================================================== */
:root{
  --fs-label:12px;
  --fs-body-sm:14px;
  --fs-body:16px;
  --fs-title:20px;
  --fs-h3:24px;
  --fs-h2:28px;
  --fs-h1:32px;
  --fs-display:48px;
  --fs-display-l:58px;
  --fs-display-x:64px;
  /* Shell chrome heights — the collapsed UI bars offset from these so they
     clear both the tab bar and the canvas ruler instead of sitting on it. */
  --chrome-h:42px;
  --ruler-h:23px;
}

.shell-body{flex:1;display:flex;min-height:0;position:relative}

/* ---- Left rail ---- */
/* ===== Minimize / Expand UI (Figma ⇧⌘\) ===== */
.ui-toggle{
  position:relative;flex:none;
  width:26px;height:26px;border-radius:6px;border:0;background:transparent;
  display:flex;align-items:center;justify-content:center;
  color:var(--t3);cursor:pointer;transition:background .15s ease,color .15s ease;
}
.ui-toggle:hover{background:var(--c2,rgba(255,255,255,.07));color:var(--tx)}
.ui-toggle.on-dark{color:rgba(255,255,255,.72)}
.ui-toggle.on-dark:hover{background:rgba(255,255,255,.12);color:#fff}
.ui-tip{
  position:absolute;top:calc(100% + 8px);right:0;
  display:flex;align-items:center;gap:7px;white-space:nowrap;
  background:#1E1E20;color:#fff;font-size:12px;font-weight:500;
  padding:6px 9px;border-radius:6px;box-shadow:0 6px 18px rgba(0,0,0,.4);
  opacity:0;visibility:hidden;transition:opacity .12s ease;pointer-events:none;z-index:120;
}
.ui-tip.below{left:0;right:auto}
.ui-tip kbd{font:inherit;color:rgba(255,255,255,.5)}
.ui-toggle:hover .ui-tip{opacity:1;visibility:visible}
.rail-head-row{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}

/* collapse both panels + the icon strip */
#shell.ui-min .iconstrip,
#shell.ui-min .rail,
#shell.ui-min .inspector{display:none !important}

/* floating bars, hidden until minimized */
.mini-bar{display:none}
#shell.ui-min .mini-bar{
  position:fixed;
  top:calc(var(--chrome-h) + var(--ruler-h) + 16px);
  z-index:110;
  display:flex;align-items:center;gap:10px;
  max-width:calc(50vw - 24px);
  background:#2C2C2E;border-radius:11px;padding:8px 12px;
  box-shadow:0 8px 26px rgba(0,0,0,.38);
  animation:fadeUp .18s ease both;
  white-space:nowrap;
}
#shell.ui-min .mini-left{left:18px}
#shell.ui-min .mini-right{right:18px;padding:7px 8px 7px 12px}
.mini-brand{display:flex;align-items:center;flex:none}
.mini-name{font-size:14px;font-weight:600;color:#fff;white-space:nowrap}
.mini-badge{font-size:12px;color:#9AA0A6;white-space:nowrap}
.mini-avatar{width:24px;height:24px;border-radius:50%;overflow:hidden;flex:none;background:#3873E1;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;color:#fff}
.mini-avatar img{width:100%;height:100%;object-fit:cover;display:block}
.mini-zoom{display:flex;align-items:center;gap:4px;font-size:12px;color:rgba(255,255,255,.8);white-space:nowrap}
.mini-play{display:flex;align-items:center;color:rgba(255,255,255,.75)}
.mini-cta{
  background:#0D99FF;color:#fff;font-size:12px;font-weight:600;
  padding:6px 13px;border-radius:7px;text-decoration:none;white-space:nowrap;
  border:0;font-family:inherit;cursor:pointer;display:inline-flex;align-items:center;
}
.mini-cta:hover{background:#0B87E3}

/* ---- "Let's Connect" dropdown — same menu reused under the inspector's
   button and the floating mini-bar's, opened/closed by one delegated
   listener (bindConnectMenus) so re-rendering the inspector never leaves a
   stale handler behind. ---- */
.connect-wrap{position:relative}
.connect-menu{
  position:absolute;top:calc(100% + 8px);right:0;z-index:20;min-width:168px;
  background:#fff;border:1px solid var(--wline,#E7E7EA);border-radius:12px;
  box-shadow:0 12px 28px rgba(0,0,0,.16);padding:6px;display:flex;flex-direction:column;gap:2px;
}
/* A plain class rule and the browser's built-in [hidden]{display:none} are
   equal specificity, and author CSS always wins that tie over the UA
   stylesheet — so .connect-menu{display:flex} above was quietly overriding
   `hidden` and leaving the menu visible from first paint. The extra
   attribute selector here outranks it so `hidden` actually hides it again. */
.connect-menu[hidden]{display:none}
.connect-menu-item{
  display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:8px;
  font-size:13px;font-weight:500;color:var(--ink,#1A1A1E);text-decoration:none;
}
.connect-menu-item:hover{background:var(--soft,#F5F5F7)}
.connect-menu-item svg{flex:none;color:var(--fg,#0D99FF)}

/* Icon strip — shown on home, projects and about; hidden on case detail.
   Proportioned from the Figma reference, where the tool rail is 68px against a
   335px panel; 52px against our 262px rail matches. */
.iconstrip{display:none}
#shell.has-strip .iconstrip{
  display:flex;flex-direction:column;align-items:center;
  width:52px;flex:none;
  background:var(--c0);border-right:1px solid var(--line);
  color:var(--t3);user-select:none;
}
.iconstrip .is-brand{height:41px;display:flex;align-items:center;justify-content:center;flex:none}
.iconstrip .is-divider{width:24px;height:1px;background:var(--line);flex:none;margin:2px 0 8px}
.iconstrip .is-items{display:flex;flex-direction:column;align-items:center;gap:5px;width:100%}
.iconstrip .is-item{
  width:32px;height:32px;border-radius:7px;
  display:flex;align-items:center;justify-content:center;
  color:var(--t3);cursor:default;transition:background .15s ease,color .15s ease;
}
.iconstrip .is-item:hover{background:var(--c1);color:var(--t2)}
.iconstrip .is-item.on{background:var(--c1);color:var(--tx)}

.rail{
  width:262px;flex:none;background:var(--c1);border-right:1px solid var(--line);
  display:flex;flex-direction:column;overflow-y:auto;color:var(--t2);font-size:14px;
}
/* The case rail is Pages + Frames now, the same shape as every other page's
   rail, so it takes the same width. It was 340px to fit the conversation
   panel that used to live here. */
.rail.case-mode{width:262px}
.rail-head{padding:12px 14px 10px}
.rail-head .who{display:flex;align-items:center;gap:6px;font-size:14px;font-weight:600;color:var(--tx)}
.rail-head .who svg{color:var(--t3)}
.rail-head .drafts{font-size:12px;color:var(--t3);margin-top:2px}
.rail-divider{height:1px;background:var(--line);margin:4px 14px 6px}
.rail-section{padding:2px 10px 8px}
.rail-section-head{display:flex;align-items:center;padding:4px 6px 8px;color:var(--t2)}
.rail-section-head span{font-size:12px;font-weight:500}
.rail-list{display:flex;flex-direction:column;gap:1px}
.rail-item{padding:7px 10px;border-radius:6px;cursor:pointer;color:var(--t2);font-size:14px}
.rail-item:hover,.rail-item.active{background:var(--c2);color:#fff}
.rail-layers-label{display:flex;align-items:center;gap:6px;padding:6px 0;font-size:12px;font-weight:500;color:var(--t2)}
.rail-layers{padding:0 14px;display:flex;flex-direction:column;gap:1px}
.rail-layer{display:flex;align-items:center;gap:8px;padding:6px 8px 6px 18px;border-radius:6px;cursor:pointer;font-size:12px;color:var(--t2)}
.rail-layer:hover{background:var(--c2);color:#fff}

.rail-back{display:flex;align-items:center;gap:7px;padding:7px 8px;border-radius:7px;font-size:12px;font-weight:500;color:var(--t2);cursor:pointer;margin:2px 0 0}
.rail-back:hover{background:var(--c2);color:#fff}
.rail-index-label{font-size:12px;font-weight:500;color:var(--t2);margin:16px 14px 10px}
.rail-index{display:flex;flex-direction:column;gap:1px;padding:0 14px}
.rail-index-item{font-size:14px;padding:7px 10px;border-radius:6px;cursor:pointer;color:#B3B3B3}
.rail-index-item:hover{background:var(--c2)}
.rail-index-item.active{color:#fff;background:#383838}

/* ---- Canvas area ---- */
.canvas-wrap{flex:1;position:relative;min-width:0;background:var(--desk)}
.corner{position:absolute;top:0;left:0;width:23px;height:23px;background:var(--c1);border-right:1px solid var(--line);border-bottom:1px solid var(--line);z-index:6}
.ruler{position:absolute;background:var(--c1);z-index:5;overflow:hidden}
.ruler-h{top:0;left:23px;right:0;height:23px;border-bottom:1px solid var(--line);
  background-image:repeating-linear-gradient(90deg,transparent 0,transparent 47px,#3A3A3C 47px,#3A3A3C 48px);}
.ruler-v{top:23px;left:0;bottom:0;width:23px;border-right:1px solid var(--line);
  background-image:repeating-linear-gradient(180deg,transparent 0,transparent 47px,#3A3A3C 47px,#3A3A3C 48px);}
.ruler span{position:absolute;font-size:9px;color:var(--t2);font-family:'Space Grotesk',sans-serif}
.ruler-v span{font-size:8.5px;transform:rotate(-90deg);transform-origin:top left;white-space:nowrap}

.canvas{
  position:absolute;top:23px;left:23px;right:0;bottom:0;
  overflow-y:auto;overflow-x:hidden;scroll-behavior:smooth;
}
.canvas-inner{width:1280px;margin:24px auto;padding:0}

.crumb{
  display:flex;align-items:center;gap:7px;margin:0 0 10px 4px;color:var(--t3);
  font-size:12px;font-weight:500;
}
.crumb .accent{color:var(--fg)}
.crumb-case{font-family:'Space Grotesk',sans-serif}

.sheet{
  background:var(--soft, #fff);border-radius:6px;color:var(--ink);
  box-shadow:0 1px 0 rgba(0,0,0,.04),0 24px 60px -30px rgba(0,0,0,.28);
}
.canvas-inner.case-dark .sheet{background:#0B0B0F;box-shadow:0 1px 0 rgba(0,0,0,.04),0 24px 60px -30px rgba(0,0,0,.6)}
.sheet-flat{background:#fff}
.canvas-inner.case-dark .sheet-flat{background:#0B0B0F}

/* ---- Case study: full-bleed (no Figma-canvas frame chrome) ---- */
.canvas-wrap.case-fullbleed .corner,
.canvas-wrap.case-fullbleed .ruler-h,
.canvas-wrap.case-fullbleed .ruler-v{display:none}
.canvas-wrap.case-fullbleed .canvas{top:0;left:0}
.canvas-wrap.case-fullbleed .canvas{background:var(--soft,#fff)}
.canvas-wrap.case-fullbleed .canvas-inner{width:100%;min-height:100%;margin:0;padding:36px 56px;background:var(--soft,#fff)}
.canvas-wrap.case-fullbleed .canvas-inner.case-dark{background:#0B0B0F}
.canvas-wrap.case-fullbleed .sheet{background:transparent;border-radius:0;box-shadow:none;color:inherit}
.canvas-wrap.case-fullbleed .canvas-inner.case-dark .sheet{background:transparent;box-shadow:none}
.canvas-wrap.case-fullbleed .crumb{margin:0 0 20px 0;font-size:12px}

/* ---- Right inspector ---- */
.inspector{
  width:262px;flex:none;background:var(--c1);border-left:1px solid var(--line);
  display:flex;flex-direction:column;overflow-y:auto;color:var(--t2);
}
.insp-top{display:flex;align-items:center;gap:10px;padding:9px 12px}
.insp-avatar{width:26px;height:26px;border-radius:50%;background:var(--fg);color:#fff;font-size:12px;font-weight:700;display:flex;align-items:center;justify-content:center;flex:none;overflow:hidden}
.insp-avatar img{width:100%;height:100%;object-fit:cover;display:block}
.insp-avatar img{width:100%;height:100%;object-fit:cover}
.insp-top .connect-wrap{margin-left:auto}
.insp-connect{padding:6px 12px;border-radius:7px;background:var(--fg);color:#fff;font-size:12px;font-weight:600;
  cursor:pointer;border:0;font-family:inherit;display:inline-flex;align-items:center;gap:5px}
.insp-connect svg{flex:none;transition:transform .15s ease}
.insp-connect[aria-expanded="true"] svg{transform:rotate(180deg)}
.insp-tabs{display:flex;align-items:center;gap:16px;padding:2px 14px 10px;border-bottom:1px solid var(--line)}
.insp-tab{font-size:14px;font-weight:600;color:var(--tx);padding-bottom:8px;border-bottom:1.5px solid var(--tx);margin-bottom:-9px}
.insp-tab.dim{font-weight:500;color:var(--t3);border-bottom:none}
.insp-zoom{margin-left:auto;font-size:12px;color:var(--t2)}

.insp-body{padding:16px 14px 26px;display:flex;flex-direction:column;gap:18px}
.insp-divider{height:1px;background:var(--line)}
.insp-label{font-size:12px;font-weight:700;letter-spacing:.11em;color:var(--t3);margin-bottom:12px}

.about-row{display:flex;align-items:center;gap:14px}
.about-photo-round{width:64px;height:64px;flex:none;border-radius:50%;overflow:hidden;background:var(--fg)}
.about-photo-round img{width:100%;height:100%;object-fit:cover}
.about-name{font-size:16px;font-weight:700;color:var(--tx)}
.about-role{font-size:14px;color:var(--t2);margin-top:3px}
.about-loc{font-size:12px;color:var(--t3);margin-top:1px}
.open-pill{
  display:inline-flex;align-self:flex-start;align-items:center;gap:8px;margin-top:16px;padding:9px 18px;
  border-radius:20px;border:1px solid rgba(52,199,120,.4);color:#34C778;font-size:12px;font-weight:600;
}
.open-pill .dot{width:8px;height:8px;border-radius:50%;background:#34C778}
.about-blurb{font-size:12px;line-height:1.6;color:var(--t3);margin-top:16px}

.chip-wrap{display:flex;gap:8px;flex-wrap:wrap}
.chip-dark{padding:8px 15px;border-radius:20px;border:1px solid var(--c3);background:rgba(255,255,255,.02);font-size:12px;font-weight:500;color:var(--t2)}
.chip-dark:hover{border-color:var(--fg);color:var(--tx)}
.chip-tool{display:inline-flex;align-items:center;gap:8px;padding:7px 14px 7px 9px;border-radius:20px;border:1px solid var(--c3);background:rgba(255,255,255,.02);font-size:12px;font-weight:500;color:var(--t2)}
.chip-tool svg{width:15px;height:15px;flex:none;display:block}

.job-mini{display:flex;flex-direction:column;gap:16px}
.job-mini .jcompany{font-size:14px;font-weight:700;color:var(--tx)}
.job-mini .jrole{font-size:12px;color:var(--t2);margin-top:2px}
.job-mini .jdur{font-size:12px;color:var(--t3);margin-top:2px}

.edu-mini{padding:12px 13px;border-radius:11px;background:rgba(255,255,255,.02);border:1px solid var(--c3);display:flex;gap:11px;align-items:flex-start}
/* A 30px badge can only carry the arc-and-GCU monogram — the full lockup's
   wordmark would render at about 2px here, which is why the name stays in the
   text beside it. White plate so the navy artwork reads on this dark panel. */
.edu-logo{width:30px;height:30px;flex:none;border-radius:7px;background:#fff;padding:3px;box-sizing:border-box}
.edu-logo img{width:100%;height:100%;object-fit:contain;display:block}
.edu-mini-title{font-size:12px;font-weight:600;color:var(--tx)}
.edu-mini-sub{font-size:12px;color:var(--t3);margin-top:3px}

.case-insp-tag{font-size:12px;font-weight:700;letter-spacing:.11em;color:var(--fg);margin-bottom:12px}
.case-insp-title{font-size:16px;font-weight:700;color:var(--tx);line-height:1.25}
.case-insp-sub{font-size:12px;color:var(--t3);margin-top:4px}
.outcome-mini{padding:14px;border-radius:12px;background:rgba(255,255,255,.02);border:1px solid var(--c3)}
/* The reference portfolio's outcome numbers read green regardless of the
   project's own accent colour — kept literal rather than var(--fg) so it
   stays true to that design instead of following each case's theme. */
.outcome-mini .val{font-size:20px;font-weight:800;letter-spacing:-.02em;color:#34C778}
.outcome-mini .lbl{font-size:12px;color:var(--t2);margin-top:2px}
.detail-row{display:flex;justify-content:space-between;gap:10px;font-size:12px}
.detail-row .k{color:var(--t3)}
.detail-row .v{color:var(--tx);font-weight:600;text-align:right}
.status-shipped{display:inline-flex;align-items:center;gap:6px;color:#34C778!important}
.status-dot{width:7px;height:7px;border-radius:50%;background:#34C778;flex:none}

/* ---- Up next card ---- */
.up-next-card{
  display:block;padding:14px 15px;border-radius:12px;cursor:pointer;
  background:color-mix(in srgb, var(--fg) 13%, var(--c1));
  border:1px solid color-mix(in srgb, var(--fg) 34%, transparent);
  transition:border-color .15s ease;
}
.up-next-card:hover{border-color:var(--fg)}
.up-next-label{font-size:11px;font-weight:700;letter-spacing:.1em;color:var(--t2);margin-bottom:8px}
.up-next-title{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:14px;font-weight:700;color:var(--tx)}
.up-next-title svg{flex:none;color:var(--fg)}
.up-next-sub{font-size:12px;color:var(--t2);margin-top:6px}

/* ---- Audio overview ---- */
.audio-ov{display:flex;flex-direction:column;gap:10px}
.audio-ov-top{display:flex;align-items:center;gap:7px}
.audio-ov-top svg{color:var(--fg);flex:none}
.audio-ov-label{font-size:11px;font-weight:700;letter-spacing:.1em;color:var(--fg)}
.audio-ov-dur{margin-left:auto;font-size:11px;color:var(--t3)}
.audio-ov-sub{font-size:12px;line-height:1.5;color:var(--t2)}
/* flex-start (not center) here on purpose: centering the row against the
   track's full box — bar + the times line beneath it — pulls the button
   down past the bar itself, since the times line adds height the button
   has no counterpart for. Anchoring both to the top and nudging the track
   down by half the button's height instead lines the button up with just
   the bar, which is the pairing that reads as "aligned" — the times sit
   below both, same as before. */
.audio-ov-row{display:flex;align-items:flex-start;gap:12px}
.audio-ov-btn{
  flex:none;width:32px;height:32px;border-radius:50%;background:var(--fg);color:#fff;border:0;padding:0;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
}
.audio-ov-btn svg{margin-left:1.5px}
.audio-ov-btn.playing svg{margin-left:0}
.audio-ov-track{flex:1;min-width:0;padding-top:14px}
.audio-ov-bar{height:4px;border-radius:2px;background:var(--c3);overflow:hidden}
.audio-ov-fill{height:100%;background:var(--fg);border-radius:2px}
.audio-ov-times{display:flex;justify-content:space-between;margin-top:6px;font-size:11px;color:var(--t3)}

/* ============================================================
   Page content (rendered inside .sheet)
   ============================================================ */
.section{position:relative;padding:60px 64px}
.section + .section{border-top:none}

/* Hero */
/* Pulled out of an inline style so mobile-native-home (below) can override
   it — the desktop numbers (fixed 832px min-height, centred flex) assume the
   1280px scaled frame and would leave a phone staring at empty space. */
.home-hero{padding:64px;overflow:visible;min-height:832px;display:flex;align-items:center;justify-content:center}
.hero-bg{position:absolute;inset:0;background:radial-gradient(680px 420px at 82% 6%,color-mix(in srgb,var(--fg) 12%,transparent),transparent 70%);pointer-events:none}
.hero-inner{position:relative;text-align:center}
.hero-wave{opacity:0;animation:fadeUp .7s cubic-bezier(.2,.7,.3,1) .02s forwards;display:inline-flex;align-items:center;gap:8px;font-size:14px;font-weight:600;color:var(--dim)}
.hero-wave .emoji{font-size:16px;line-height:1;display:inline-block;transform-origin:70% 80%;animation:wave 2.4s ease-in-out infinite}
.hero-title{
  opacity:0;animation:fadeUp .7s cubic-bezier(.2,.7,.3,1) .08s forwards;
  margin:22px auto 0;font-size:48px;line-height:1.14;font-weight:700;letter-spacing:-.02em;color:var(--ink);max-width:720px;
}
.hero-edit{position:relative;display:inline-block;border:1px solid #0D99FF;padding:0 1px}
.hero-caret{display:inline-block;width:1.5px;height:.86em;background:var(--ink);vertical-align:-.06em;margin:0 -.75px;animation:figblink 1.06s steps(1) infinite}
.hero-handle{position:absolute;width:7px;height:7px;background:#fff;border:1px solid #0D99FF;border-radius:1px;transform:translate(-50%,-50%)}
.hero-gradient-text{
  background:linear-gradient(90deg,var(--fg),#7C3AED,var(--fg));background-size:200% auto;
  -webkit-background-clip:text;background-clip:text;color:transparent;animation:shimmer 5s linear infinite;
}
.hero-sub{opacity:0;animation:fadeUp .7s cubic-bezier(.2,.7,.3,1) .16s forwards;margin:22px auto 0;max-width:560px;font-size:16px;line-height:1.7;color:var(--dim)}
.hero-pills{position:relative;height:80px;margin-top:20px}
.pill{
  position:absolute;display:inline-block;opacity:0;animation:pillIn .7s cubic-bezier(.2,.7,.3,1) forwards;
}
.pill .float{animation:floaty 6.8s ease-in-out infinite}
.pill .tag{
  display:inline-block;padding:7px 14px;border-radius:18px;font-size:12px;font-weight:600;
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);white-space:nowrap;
}

/* Chat-style hero banner */
.chat-hero{position:relative;text-align:center;max-width:900px;margin:0 auto}
.chat-greeting{font-size:16px;font-weight:500;color:var(--dim);margin-bottom:36px;font-family:'Space Grotesk',sans-serif}
.chat-greeting .emoji{display:inline-block;transform-origin:70% 80%;animation:wave 2.4s ease-in-out infinite}
.chat-headline{margin:0;font-weight:400;font-family:'Sprat','Space Grotesk',sans-serif}
.chat-line{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:16px}
.chat-line + .chat-line{margin-top:6px}
.ctx{font-size:clamp(48px,6.05vw,64px);line-height:1.05;letter-spacing:-.02em;white-space:nowrap}
.ctx.black{color:var(--ink);font-weight:400}
.ctx.gray{color:#8f8f8f;font-weight:400}
.collage{position:relative;width:98px;height:70px;border-radius:17px;overflow:hidden;transform:rotate(-6deg);box-shadow:0 13px 22px rgba(0,0,0,.22);background:#efe6d2;flex:none}
.collage .frame{position:absolute;inset:0;background-repeat:no-repeat;background-position:center;background-size:cover;opacity:0;animation:collage-cycle 9s ease-in-out infinite}
.collage .f1{animation-delay:0s}
.collage .f2{animation-delay:3s}
.collage .f3{animation-delay:6s}
@keyframes collage-cycle{
  0%{opacity:0}
  4%{opacity:1}
  30%{opacity:1}
  36%{opacity:0}
  100%{opacity:0}
}
.logo-box-dark{position:relative;width:98px;height:70px;border-radius:17px;background:#111214;display:flex;align-items:center;justify-content:center;overflow:hidden;box-shadow:0 13px 24px rgba(0,0,0,.28);flex:none}
.word-rotator{position:relative;width:100%;height:26px}
.word-rotator .word{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:28px;font-weight:800;font-style:italic;letter-spacing:.01em;color:#d6d6d6;opacity:0;transform:translateY(16px);animation:word-cycle 8s cubic-bezier(.4,0,.2,1) infinite}
.word-rotator .w1{animation-delay:0s}
.word-rotator .w2{animation-delay:2s}
.word-rotator .w3{animation-delay:4s}
.word-rotator .w4{animation-delay:6s}
@keyframes word-cycle{
  0%{opacity:0;transform:translateY(16px)}
  6%{opacity:1;transform:translateY(0)}
  19%{opacity:1;transform:translateY(0)}
  25%{opacity:0;transform:translateY(-16px)}
  100%{opacity:0;transform:translateY(-16px)}
}
.chatbar{position:relative;margin:48px auto 0;width:100%;max-width:none;display:flex;align-items:center;gap:9px;background:#fff;border:1px solid var(--wline);border-radius:999px;padding:9px 10px;box-shadow:0 8px 21px rgba(0,0,0,.06);transition:border-color .25s ease,box-shadow .25s ease}
.chatbar.focused{border-color:#b9b9b9;box-shadow:0 8px 24px rgba(0,0,0,.1),0 0 0 4px rgba(13,153,255,.12)}
.chatbar input{flex:1;border:0;outline:0;font-family:inherit;font-size:12px;color:var(--ink);background:transparent;padding:3px}
.chatbar input::placeholder{color:#9a9a9a}
.chatbar-icon{flex:none;width:26px;height:26px;border-radius:50%;border:0;background:transparent;color:#4a4a4a;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s ease,transform .12s ease}
.chatbar-icon:hover{background:var(--soft)}
.chatbar-icon.dark{background:#111;color:#fff}
.chatbar-icon.dark:hover{background:#000}
.chatbar-icon.pressed{transform:scale(.86)}

/* Animated demo cursor — shows the composer being "used" */
.demo-cursor{
  position:absolute;top:0;left:0;width:20px;height:20px;pointer-events:none;z-index:40;opacity:0;
  transform:translate(-15%,-15%) scale(1);
  transition:left .55s cubic-bezier(.65,0,.35,1),top .55s cubic-bezier(.65,0,.35,1),opacity .3s ease,transform .15s ease;
  filter:drop-shadow(0 3px 6px rgba(0,0,0,.35));
}
.demo-cursor svg{width:100%;height:100%;display:block}
.demo-cursor.show{opacity:1}
.demo-cursor.pressing{transform:translate(-15%,-15%) scale(.8)}
/* "Start from an example" project row (Figma Make style) */
/* Section header sized against the Figma Make reference itself: its "Start
   from an example" label reads only slightly larger than the card titles
   below it, not the 20px/17px gap this used to carry. */
.examples-row{margin-top:40px;text-align:left}
.examples-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.examples-label{font-size:16px;font-weight:700;letter-spacing:-.01em;color:var(--ink)}
.examples-nav{display:flex;align-items:center;gap:16px}
.examples-see-more{font-size:14px;font-weight:600;color:#2563EB;text-decoration:none}
.examples-see-more:hover{text-decoration:underline}
/* Hover-narration toggle — opt-in, sits with the other header controls.
   Labelled rather than icon-only: a bare speaker icon reads as decoration and
   nobody discovers that it has to be armed first. */
.narrate-btn{
  position:relative;flex:none;
  height:34px;border-radius:20px;padding:0 14px 0 12px;gap:7px;
  border:1px solid var(--wline);background:#fff;
  display:flex;align-items:center;justify-content:center;
  font-family:inherit;font-size:14px;font-weight:600;
  color:var(--dim);cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease;
}
.narrate-label{white-space:nowrap}
.narrate-btn:hover{background:var(--soft);color:var(--ink);border-color:#C9CDD4}
.narrate-btn.on{background:#EAF2FF;border-color:#B9D4FF;color:#2563EB}
.narrate-btn.on .narrate-label::after{content:"ing"}
/* failure surface — appears only when speech actually fails */
.narrate-note{
  position:absolute;top:calc(100% + 7px);right:0;
  background:#B3261E;color:#fff;font-size:12px;font-weight:600;
  padding:5px 9px;border-radius:6px;white-space:nowrap;z-index:20;
}
.narrate-btn .ico-on{display:none}
.narrate-btn.on .ico-on{display:block}
.narrate-btn.on .ico-off{display:none}

/* the card being read aloud */
.example-card.speaking .ex-thumb{box-shadow:0 0 0 2px #2563EB,0 10px 24px rgba(0,0,0,.16)}
.example-card.speaking .ex-title{color:#2563EB}

.examples-arrows{display:flex;gap:8px}
.examples-arrow{width:34px;height:34px;border-radius:50%;border:1px solid var(--wline);background:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#333;transition:background .15s ease}
.examples-arrow:hover{background:var(--soft)}
.examples-track{display:flex;gap:28px;overflow-x:auto;scroll-behavior:smooth;scrollbar-width:none;padding-bottom:2px}
.examples-track::-webkit-scrollbar{display:none}
/* Three cards fill the visible width exactly, as before (56px = the two gaps
   between them), but they no longer shrink to fit — so the rest of the projects
   overflow the track and the chevrons have somewhere to scroll. */
.example-card{flex:0 0 calc((100% - 56px) / 3);min-width:0;cursor:pointer;text-align:left}
.examples-arrow:disabled{opacity:.35;cursor:default}
/* Thumb proportion matches the Figma Make example cards (420 × 240 ≈ 1.75:1)
   rather than the old fixed 118px, which read as a letterbox at ~2.5:1. */
.example-card .ex-thumb{width:100%;aspect-ratio:420/240;height:auto;border-radius:12px;overflow:hidden;background:#eee;box-shadow:0 4px 14px rgba(0,0,0,.08);transition:box-shadow .25s ease}
@supports not (aspect-ratio:1/1){.example-card .ex-thumb{height:168px}}
.example-card .ex-thumb img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .35s ease}
.example-card:hover .ex-thumb{box-shadow:0 10px 24px rgba(0,0,0,.16)}
.example-card:hover .ex-thumb img{transform:scale(1.08)}
/* Type scale pulled back down to the Figma Make reference's actual card
   scale — the previous 17/15px pass overshot it and read more like a case
   study's own heading than a compact "browse" card. */
/* No reserved height here any more: it used to hold space for two title
   lines so a one-line title ("Workspace") lined up with a two-line one
   ("End-to-end Data Management"), but that left a slab of dead air under
   every short title. The pills row is now the shared bottom anchor instead,
   so the description can sit right under whatever height the title is. */
.example-card .ex-title{margin-top:12px;font-size:14.5px;line-height:1.3;font-weight:600;letter-spacing:-.01em;color:var(--ink);transition:color .2s ease}
.example-card:hover .ex-title{color:#2563EB}
.example-card .ex-sub{margin-top:5px;font-size:12.5px;line-height:1.45;color:var(--dim)}
.ex-pills{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.ex-pill{padding:3px 9px;border-radius:20px;font-size:10.5px;font-weight:500;color:var(--dim);background:var(--soft);border:1px solid var(--wline)}
.suggest-pill:hover{background:var(--soft);border-color:#dcdcdc}

/* Companies */
.companies-label{font-size:12px;font-weight:400;letter-spacing:.02em;color:var(--dim);margin-bottom:44px;text-align:center;display:flex;align-items:center;justify-content:center;gap:8px}
.companies-label .dot{width:8px;height:8px;border-radius:50%;background:#22C55E;flex-shrink:0}
.companies-label b{font-weight:800}
.marquee-mask{position:relative;-webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.marquee-track{display:flex;width:max-content;gap:56px;animation:marquee 22s linear infinite;filter:grayscale(1);opacity:.6;align-items:center}
.marquee-track span{font-size:16px;font-weight:700;color:#111;white-space:nowrap}

/* Featured */
.featured-title{margin:0 0 32px;font-size:24px;font-weight:700;letter-spacing:-.015em;color:var(--ink);max-width:640px;text-align:center;margin-left:auto;margin-right:auto}
.featured-card{display:flex;border-radius:16px;overflow:hidden;background:var(--soft);border:1px solid var(--wline);min-height:480px}
.featured-info{flex:none;width:320px;padding:32px 28px;display:flex;flex-direction:column}
.featured-nav{display:flex;gap:8px}
.featured-nav button{width:34px;height:34px;border-radius:50%;background:#fff;border:1px solid var(--wline);display:inline-flex;align-items:center;justify-content:center;color:var(--dim);cursor:pointer}
.featured-body{margin-top:auto}
.featured-body .ftitle{font-size:16px;font-weight:600;color:var(--ink)}
.featured-body .ftag{font-size:12px;color:var(--dim);margin-top:3px}
.featured-body p{margin:14px 0 0;font-size:12px;line-height:1.55;color:var(--dim)}
.featured-cta{display:inline-flex;margin-top:22px;padding:10px 20px;border-radius:8px;background:#0D99FF;color:#fff;font-size:14px;font-weight:600}
.featured-image{flex:1;padding:24px 24px 24px 0;display:flex}
.featured-image .ph{flex:1;border-radius:12px;overflow:hidden;background:var(--wline)}
.featured-image img{width:100%;height:100%;object-fit:cover}

/* Latest work */
.grid-head{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:24px}
.grid-head h2{margin:0;font-size:16px;font-weight:600;letter-spacing:-.01em;color:var(--ink)}
.case-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
.case-grid.wide{grid-template-columns:repeat(2,1fr)}
.case-card{background:#fff;border:1px solid var(--wline);border-radius:9px;overflow:hidden;cursor:pointer;transition:transform .2s ease,box-shadow .2s ease}
.case-card:hover{transform:translateY(-3px);box-shadow:0 18px 34px -20px rgba(20,25,80,.3)}
.case-card .thumb{height:130px;background:var(--soft);overflow:hidden}
.case-card.wide .thumb{height:188px}
.case-card .thumb img{width:100%;height:100%;object-fit:cover}
.case-card .meta{display:flex;align-items:center;gap:10px;padding:12px 14px}
.case-card .swatch{width:20px;height:20px;border-radius:5px;flex:none}
.case-card .ctitle{font-size:12px;font-weight:600;color:var(--ink);line-height:1.3}
.case-card.wide .ctitle{font-size:12px}
.case-card .csub{font-size:12px;color:var(--t3-fallback,#808080);margin-top:1px}

/* Footer */
.home-footer{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:44px;text-align:center}
.footer-cta{font-size:24px;font-weight:700;letter-spacing:-.015em;color:var(--ink)}
.social-row{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}
.social-row a{display:inline-flex;align-items:center;gap:9px;padding:6px 16px;border-radius:20px;background:#F5F5F6;border:1px solid #E3E3E6;color:var(--ink);font-size:12px;transition:transform .2s ease,background .2s ease}
.social-row a:hover{transform:translateY(-2px);background:#ECECEF}
.legal-row{display:flex;justify-content:space-between;margin-top:90px;padding-top:18px;padding-bottom:20px;border-top:1px solid var(--wline);font-size:12px;color:var(--dim)}

/* Projects page */
.projects-title{margin:0 0 8px;font-size:32px;font-weight:400;letter-spacing:-.02em;color:var(--ink);font-family:'Sprat','Space Grotesk',sans-serif;text-align:center}
.projects-sub{margin:0 auto 30px;max-width:640px;font-size:16px;line-height:1.6;color:var(--dim);text-align:center}

/* Projects page — list view with hover-reveal image */
.proj-list{display:flex;flex-direction:column;margin-top:8px}
.proj-list-head,.proj-row{display:grid;grid-template-columns:56px 1fr 170px 120px;column-gap:16px}
.proj-list-head{align-items:center;padding:0 4px 12px;border-bottom:1px solid var(--wline);font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--dim)}
.proj-row{align-items:start;padding:26px 4px;border-bottom:1px solid var(--wline);cursor:pointer;transition:background .15s ease}
.proj-row:hover{background:color-mix(in srgb,var(--fg) 5%,transparent)}
.proj-row .col-idx{font-size:12px;color:var(--dim);align-self:start;margin-top:3px}
.proj-row .col-title-wrap{display:flex;flex-direction:column;gap:9px}
.proj-row .col-title{font-size:24px;font-weight:500;color:var(--ink);font-family:'Sprat','Space Grotesk',sans-serif;transition:color .15s ease}
.proj-row:hover .col-title{color:var(--fg)}
.proj-row .col-desc{font-size:16px;line-height:1.62;color:var(--dim);max-width:620px}
/* Same tag pills as the Home cards, wrapped to fit the 170px category
   column — most projects run 3-4, so this is 1-3 short rows rather than
   the single all-caps category label it used to be. */
.proj-row .col-tag{display:flex;flex-wrap:wrap;gap:6px;align-self:start;margin-top:3px}
.proj-row .col-tag .tag-pill{display:inline-block;font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;padding:4px 10px;border-radius:20px;border:1px solid var(--wline);color:var(--dim)}
.proj-row .col-meta{font-size:14px;color:var(--dim);text-align:right;align-self:start;margin-top:3px}

/* Positioning, the fade, the tilt and the overall size. The mockup block lower
   down owns the card and the device; everything here is the presentation of it.

   The card leans by --tilt, which bindProjectRowHover alternates per row so
   consecutive previews lean opposite ways. scale() below is what sets the
   displayed size — the geometry inside the card is all in fixed px, so scaling
   here shrinks the card, the device and the shadow together and keeps them in
   proportion. Change the scale, not the internal numbers.

   Rotating this element used to push the card outside the scrolling canvas,
   which clipped it and read as a cropped device. The tilt is not the problem —
   the fix is the clamp in bindProjectRowHover that keeps the box inside the
   section. A 504x360 box at scale .8 and 6deg has a visual bounding box of
   about 431x329, i.e. smaller than the layout box in both directions, so
   clamping the layout box is enough to guarantee the visible card fits. */
.proj-hover-img{
  position:absolute;top:0;left:0;padding:0;
  pointer-events:none;opacity:0;z-index:20;
  transform:scale(.75) rotate(var(--tilt,-6deg));
  transition:opacity .18s ease,transform .18s ease;
}
.proj-hover-img.visible{opacity:1;transform:scale(.8) rotate(var(--tilt,-6deg))}

/* About page */
.about-photo-top{border-radius:18px;overflow:hidden;height:640px;background:var(--soft);margin-bottom:48px;display:flex;align-items:center;justify-content:center}
.about-photo-top img{width:auto;height:100%;max-width:100%;object-fit:contain}
.about-intro{display:block}
.about-text{display:flex;flex-direction:column;gap:18px;max-width:720px;font-size:16px;line-height:1.75;color:var(--dim);text-align:left}

.exp-grid{display:grid;grid-template-columns:1.6fr 1fr;gap:48px;align-items:start}
.exp-grid h2{margin:0 0 28px;font-size:32px;font-weight:400;letter-spacing:-.02em;color:var(--ink);font-family:'Sprat','Space Grotesk',sans-serif}
.tl-item{display:grid;grid-template-columns:22px 1fr;gap:18px}
.tl-dotwrap{display:flex;flex-direction:column;align-items:center}
.tl-dot{width:11px;height:11px;border-radius:50%;background:var(--fg);border:3px solid color-mix(in srgb,var(--fg) 20%,#fff);flex:none;margin-top:4px}
.tl-line{width:2px;flex:1;background:var(--wline)}
.tl-body{padding-bottom:30px}
.tl-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.tl-head .company{font-size:16px;font-weight:700;color:var(--ink)}
.tl-head .dur{font-size:12px;font-weight:600;color:var(--dim)}
.tl-role{font-size:14px;font-weight:600;color:var(--fg);margin-top:2px}
.tl-blurb{font-size:14px;line-height:1.65;color:var(--dim);margin-top:6px}

.side-sticky{position:sticky;top:24px;display:flex;flex-direction:column;gap:18px}
.side-card{border:1px solid var(--wline);border-radius:14px;padding:20px;background:var(--soft)}
.side-card .sname{font-size:16px;font-weight:700;color:var(--ink)}
.side-card .srole{font-size:12px;font-weight:600;color:var(--fg)}
.side-meta{display:flex;flex-direction:column;gap:6px;margin-top:12px;font-size:12px;font-weight:500;color:var(--dim)}
.side-meta span{display:flex;align-items:center;gap:8px}
.side-label{font-size:14px;font-weight:700;color:var(--ink);margin-bottom:10px}
.chip-row{display:flex;gap:8px;flex-wrap:wrap}
.chip{padding:8px 14px;border-radius:12px;border:1.5px solid var(--wline);background:#fff;font-size:12px;font-weight:600;color:var(--ink);transition:border-color .2s ease,color .2s ease}
.chip:hover{border-color:var(--fg);color:var(--fg)}
.chip.tool{padding:6px 12px;border-radius:12px;background:var(--soft);border:1px solid var(--wline);font-size:12px;font-weight:600;color:var(--dim)}

/* About — Education card in the Experience sidebar (replaces the old Skills
   chip-row now that skills have their own full-width breakdown below). */
.edu-row{display:flex;gap:12px;align-items:flex-start;margin-top:2px}
.edu-badge{width:34px;height:34px;flex:none;border-radius:8px;background:#fff;border:1px solid var(--wline);padding:4px;box-sizing:border-box}
.edu-badge img{width:100%;height:100%;object-fit:contain;display:block}
.edu-degree{font-size:13px;font-weight:700;color:var(--ink);line-height:1.35}
.edu-school{font-size:12px;color:var(--dim);margin-top:4px}
.edu-note{font-size:12px;color:var(--dim);margin-top:1px}

/* About — the three-column "what skills mean in practice" breakdown,
   sitting between Experience and the Tools marquee. Column label matches
   the small caps/blue treatment already used elsewhere (audio overview
   label, eyebrows) rather than introducing a new type style. */
.skills-groups{
  margin-top:32px;padding-top:28px;border-top:1px solid var(--wline);
  display:grid;grid-template-columns:repeat(3,1fr);gap:48px;
}
.skills-col-label{
  font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--fg);margin-bottom:14px;
}
.skills-item{font-size:15px;line-height:1.4;color:var(--ink);padding:14px 0;border-bottom:1px solid var(--wline)}
.skills-col .skills-item:last-child{border-bottom:0}

/* About — closing Contact frame. A plain white CTA card like the other two
   About frames, just with its own generous corner radius so it still reads
   as a distinct "card" rather than another content block. */
.fr.contact-fr{border-radius:20px}
.contact-section{max-width:640px}
.contact-headline{
  margin:0;font-size:38px;line-height:1.25;font-weight:400;letter-spacing:-.015em;
  color:var(--ink);font-family:'Sprat','Space Grotesk',sans-serif;
}
.contact-btns{display:flex;flex-wrap:wrap;gap:12px;margin-top:32px}
.contact-btn{
  display:inline-flex;align-items:center;gap:6px;padding:13px 22px;border-radius:10px;
  font-size:14px;font-weight:700;font-family:'Space Grotesk',sans-serif;
  transition:background .15s ease,border-color .15s ease,color .15s ease;
}
.contact-btn-primary{background:var(--fg);color:#fff}
.contact-btn-primary:hover{background:#0B87E3;color:#fff}
.contact-btn-outline{background:transparent;color:var(--ink);border:1px solid var(--wline)}
.contact-btn-outline:hover{border-color:var(--fg);color:var(--fg)}
.contact-reach{
  display:flex;align-items:center;flex-wrap:wrap;gap:12px;margin-top:26px;
  font-family:ui-monospace,'Roboto Mono',monospace;font-size:13px;color:var(--dim);
}
.contact-email{color:var(--fg);font-weight:600}
.contact-email:hover{color:#3AAEFF}
.contact-copy-btn{
  background:#fff;color:var(--ink);border:1px solid var(--wline);
  padding:6px 14px;border-radius:8px;font-size:12px;font-weight:600;cursor:pointer;
  font-family:'Space Grotesk',sans-serif;min-width:56px;text-align:center;
  transition:background .15s ease,border-color .15s ease;
}
.contact-copy-btn:hover{background:var(--soft);border-color:#C9CDD4}
/* No mobile breakpoint override here: the canvas is a fixed 1280px frame that
   the app scales down uniformly for narrow viewports (see ZOOM_MIN in
   script.js) the same way every other in-canvas heading does, rather than
   each class carrying its own responsive sizing. */

/* Case detail */
.case-crumb{font-family:'Space Grotesk',sans-serif}
.case-eyebrow{font-family:'Space Grotesk',sans-serif;font-size:14px;color:var(--dim);letter-spacing:.05em}
.case-eyebrow.accent{color:#FF5C4D;display:flex;align-items:center;gap:8px;font-weight:400}
.case-eyebrow .bar{width:14px;height:2px;background:#FF5C4D}
.case-tag{display:inline-block;margin:22px 0 0;font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--fg);background:color-mix(in srgb,var(--fg) 10%,transparent);padding:5px 11px;border-radius:13px}
.canvas-inner.case-dark .case-tag{color:#FF5C4D;background:color-mix(in srgb,#FF5C4D 16%,transparent)}
/* Same treatment as the Home hero's chat-headline: Sprat, weight 400, the
   same tracking and line-height — a case title is just a longer sentence of
   the same face, not a different one. */
/* Brought down from 48px — a full-sentence title at that size ran three
   lines tall on most cases, towering over every section heading below it
   (28-32px). 34px keeps it the biggest thing on the page without dwarfing
   the content underneath. Sub scaled down to match, so the pair still reads
   as one proportioned block rather than title-shrunk-sub-unchanged. */
.case-title{margin:14px 0 0;font-size:34px;line-height:1.2;font-weight:400;letter-spacing:-.015em;color:var(--ink);max-width:760px;font-family:'Sprat','Space Grotesk',sans-serif}
.case-sub{margin:18px 0 0;max-width:620px;font-size:17px;line-height:1.6;color:var(--dim)}
.case-facts{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin:36px 0 8px;padding:22px 0;border-top:1px solid var(--wline);border-bottom:1px solid var(--wline)}
.case-facts .k{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--t3-f,#808080)}
.canvas-inner.case-dark .case-facts .k{color:#6B6B76}
.case-facts .v{font-size:14px;font-weight:600;color:var(--ink);margin-top:5px}
.canvas-inner.case-dark .case-facts{border-color:#22222A}
.case-hero-img{height:400px;border-radius:14px;overflow:hidden;background:var(--soft);margin-top:24px}
.case-hero-img img{width:100%;height:100%;object-fit:cover}
.case-hero-img.contain{height:auto;display:flex;align-items:center;justify-content:center}
.case-hero-img.contain img{width:100%;height:auto;object-fit:contain}

.case-section{padding:56px 64px;border-top:1px solid var(--wline)}
.case-section h2{margin:18px 0 0;font-size:32px;line-height:1.2;font-weight:400;letter-spacing:-.02em;color:var(--ink);max-width:760px;font-family:'Sprat','Space Grotesk',sans-serif}
.case-section p{margin:20px 0 0;max-width:660px;font-size:16px;line-height:1.75;color:var(--dim)}
.case-quote{margin-top:24px;padding:20px 24px;border-left:3px solid var(--fg);background:var(--soft);border-radius:0 12px 12px 0;font-size:16px;font-weight:600;line-height:1.55;color:var(--ink);max-width:640px}
.canvas-inner.case-dark .case-quote{border-color:#FF5C4D;font-size:20px;font-weight:400;color:var(--dim)}

.who-grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:18px;margin-top:22px}
.who-card{padding:22px;border:1px solid var(--wline);border-radius:14px;background:var(--soft)}
.who-card .role{font-size:16px;font-weight:700;color:var(--ink)}
.who-card .tag2{font-size:14px;color:var(--fg);font-weight:600;margin-top:2px}
.who-card p{margin:12px 0 0;font-size:14px;line-height:1.6;color:var(--dim);max-width:none}

.decision-row{display:grid;grid-template-columns:44px 1fr;gap:16px;align-items:start;margin-top:16px}
.decision-num{width:44px;height:44px;border-radius:11px;background:color-mix(in srgb,var(--fg) 12%,transparent);color:var(--fg);display:flex;align-items:center;justify-content:center;font-weight:800;font-family:'Space Grotesk',sans-serif}
.decision-title{font-size:16px;font-weight:700;color:var(--ink)}
.decision-body{font-size:14px;line-height:1.6;color:var(--dim);margin-top:6px;max-width:640px}

.case-image{height:300px;border-radius:14px;overflow:hidden;background:var(--soft);margin-top:24px}
.case-image img{width:100%;height:100%;object-fit:cover}
.case-image.contain{height:auto;border:1px solid var(--wline);display:flex;align-items:center;justify-content:center}
.case-image.contain img{width:100%;height:auto;object-fit:contain}
.case-image.contain.moodboard{max-width:520px;margin-left:auto;margin-right:auto}
.case-image.contain.tall img{width:auto;max-width:100%;height:auto;max-height:900px;margin:0 auto;display:block}
.case-image.contain.tall{padding:20px}

/* Final product showcase — mockup grid (Haus case) */
.product-showcase{column-count:2;column-gap:20px;margin-top:28px}
.product-shot{break-inside:avoid;margin-bottom:20px;border-radius:14px;overflow:hidden;background:#fff;border:1px solid var(--wline);box-shadow:0 12px 28px rgba(2,10,30,.08)}
.product-shot-bar{display:flex;align-items:center;gap:6px;padding:9px 12px;background:#EDEEF2}
.product-shot-dot{width:8px;height:8px;border-radius:50%;background:#D7D9E0}
.product-shot-url{margin-left:8px;font-size:12px;color:var(--dim);background:#fff;border-radius:6px;padding:3px 10px;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.product-shot-frame{max-height:460px;overflow:hidden;background:var(--soft)}
.product-shot-frame img{width:100%;height:auto;display:block;object-fit:cover;object-position:top}
.product-shot-label{padding:12px 14px;font-size:14px;font-weight:600;color:var(--ink)}
@media (max-width:800px){.product-showcase{column-count:1}}

/* ===== Hero browser mockup (case overview) ===== */
.hero-mock{
  margin-top:34px;
  border-radius:16px;
  overflow:hidden;
  background:#fff;
  border:1px solid var(--wline);
  box-shadow:0 2px 4px rgba(10,30,66,.04), 0 18px 36px -8px rgba(10,30,66,.16), 0 48px 80px -24px rgba(10,30,66,.18);
}
.hero-mock-bar{
  display:flex;align-items:center;gap:8px;
  padding:13px 18px;
  background:linear-gradient(#FBFCFD,#F1F3F7);
  border-bottom:1px solid var(--wline);
}
.hero-mock-dot{width:11px;height:11px;border-radius:50%;flex:none}
.hero-mock-dot.r{background:#FF5F57}
.hero-mock-dot.y{background:#FEBC2E}
.hero-mock-dot.g{background:#28C840}
.hero-mock-url{
  margin-left:14px;flex:1;
  background:#fff;border:1px solid var(--wline);border-radius:7px;
  padding:5px 14px;
  font-size:12px;color:var(--dim);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.hero-mock-screen{display:block;background:var(--soft);line-height:0}
.hero-mock-screen img,
.hero-mock-screen video{width:100%;height:auto;display:block}

/* ===== Cockpit case components ===== */

/* All cockpit-specific components inherit the Voyager type stack */
.ck-layers,.ck-rules,.ck-steps,
.canvas-inner.case-cockpit .product-shot{font-family:'Roboto','Space Grotesk',sans-serif}
.ck-layer-num,.ck-rule-num{font-family:ui-monospace,'Roboto Mono',monospace !important}

/* Brief card re-themed from Haus gold onto Voyager blue */
.canvas-inner.case-cockpit .brief-card{background:#F5F8FD;border:1px solid #DCE6F8;font-family:'Roboto','Space Grotesk',sans-serif}
.canvas-inner.case-cockpit .brief-card-label{font-family:'Roboto','Space Grotesk',sans-serif;color:#1E59C7;letter-spacing:.085em}
.canvas-inner.case-cockpit .brief-grid .k{color:#0A1E42}
.canvas-inner.case-cockpit .brief-grid .v{color:#6B7280}

/* Precedence chain — first match wins, read top down.
   Four one-line entries in four full-width cards spent ~700px of scroll on 40
   words, and read as heavy as the Problem section's constraint box. The order
   still matters, so the vertical sequence stays; the card chrome does not. The
   continuous left rule ties the four into one chain, which is the job the ↓
   arrows were doing while adding three more rows of height. */
.ck-layers{list-style:none;margin:22px 0 0;padding:0 0 0 18px;border-left:2px solid #D3E0F8}
.ck-layer{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;padding:7px 0}
.ck-layer + .ck-layer{border-top:1px solid #EDF1F9}
.ck-layer-num{flex:none;font-family:ui-monospace,'Roboto Mono',monospace;font-size:12px;font-weight:700;color:#1E59C7}
.ck-layer-title{font-size:14px;font-weight:700;color:var(--ink)}
/* the description shares the line where there is room and wraps beneath the
   title where there is not, so nothing is truncated at narrow widths */
.ck-layer-desc{flex:1 1 260px;min-width:0;font-size:14px;line-height:1.55;color:var(--dim)}
.ck-layer-desc::before{content:"— "}
/* a light step chain: the builder sequence is labels, not cards */
.ck-steps{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:24px}
.ck-step{font-size:14px;font-weight:600;color:#1E59C7;background:#E9EFFC;border:1px solid #D3E0F8;border-radius:20px;padding:7px 14px}
.ck-step-sep{font-size:14px;color:#90B1EE}

/* Inheritance banner demo */

/* Two-up approach columns */

/* E2E accent override — teal instead of Voyager blue */
.canvas-inner.case-e2e{--fg:#1E59C7}
.canvas-inner.case-e2e .case-eyebrow.accent{color:#3873E1}
.canvas-inner.case-e2e .case-eyebrow .bar{background:#3873E1}
.canvas-inner.case-e2e .ck-rule-num{color:#1E59C7;background:#E9EFFC}
/* E2E persona grid: all six on one row. The frame is a fixed 1280px that gets
   transform-scaled, so the column count can be fixed — 6 × 185px + 12px gaps
   fits the 1168px content width exactly, and no media query is needed. */

/* Both Shippeo cases show tall UI screenshots — never crop them. Scoped to
   case-cockpit, which the E2E case also carries, so one rule covers both. */
.canvas-inner.case-cockpit .case-image.contain{height:auto;overflow:visible;background:transparent;border:1px solid #E5E7EB;padding:0;border-radius:10px}
/* inner radius = outer 10px minus the 1px border, so the screenshot corners sit flush inside it */
.canvas-inner.case-cockpit .case-image.contain img,
.canvas-inner.case-cockpit .case-image.contain video{width:100%;height:auto;object-fit:contain;border-radius:9px;display:block}
.canvas-inner.case-e2e .glimpse-thumb{height:auto;overflow:visible;background:transparent}
.canvas-inner.case-e2e .glimpse-thumb img{width:100%;height:auto;object-fit:contain;border:1px solid #E5E7EB;border-radius:8px}
.canvas-inner.case-e2e .brief-card{background:transparent}
.canvas-inner.case-e2e .brief-card{background:#F5F8FE;border-color:#D3E0F8}
.canvas-inner.case-e2e .brief-card-label{color:#1E59C7}

/* --- 03 / Research: compact category chart (native, so it stays crisp
   and cannot repeat the overlapping-rule bug the generated image had) --- */
.ic-chart{margin-top:22px;border:1px solid #E5E7EB;border-radius:10px;padding:20px 22px;background:#FFFFFF}
.ic-row{display:grid;grid-template-columns:minmax(0,210px) minmax(0,1fr) 30px;gap:16px;align-items:center;margin-bottom:12px}
.ic-row:last-of-type{margin-bottom:0}
.ic-label{font-size:14px;font-weight:700;color:#0A1E42;line-height:1.25;min-width:0}
.ic-track{height:10px;border-radius:6px;background:#F1F5FB}
.ic-bar{height:10px;border-radius:6px;background:#3873E1}
.ic-bar.s2{background:#6E9AEA}
.ic-bar.s3{background:#A8C3F3}
.ic-num{font-size:14px;font-weight:700;color:#1E59C7;text-align:right}

/* --- 03 / Research: the hypothesis the categorisation produced --- */
.hypo{margin-top:26px;padding:20px 22px;border-radius:10px;background:#F5F8FE;
  border:1px solid #D3E0F8;border-left:3px solid #3873E1}
.hypo-label{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:#1E59C7;margin-bottom:10px}
.canvas-inner .hypo p{margin:0;font-size:16px;line-height:1.65;color:#4B5563}
.canvas-inner .hypo p.hypo-head{font-size:24px;font-weight:700;line-height:1.35;letter-spacing:-.01em;color:#0A1E42;margin-bottom:12px}

/* --- 01 / Problem: the pain points as a plain list. Amber markers keep the
   "these are problems" signal without three boxes of chrome. --- */
.pain-list{margin:24px 0 0;padding:0;list-style:none;max-width:none}
.pain-list li{position:relative;padding-left:22px;margin-bottom:15px;font-size:16px;line-height:1.72;color:#374151}
.pain-list li:last-child{margin-bottom:0}
.pain-list li::before{content:"";position:absolute;left:2px;top:11px;width:7px;height:7px;border-radius:50%;background:#B45309}
.pain-list strong{color:#0A1E42;font-weight:700}

/* --- 02 / Impact: findings, then what is and is not provable --- */
.imp-div{height:1px;background:#E5E7EB;margin:30px 0}
.imp-list{display:flex;flex-direction:column;gap:22px}
.imp-item{min-width:0}
.imp-label{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:#1E59C7;margin-bottom:9px}
.canvas-inner .imp-item p,
.canvas-inner .imp-note p{margin:0;font-size:16px;line-height:1.62;color:#4B5563;max-width:none}
.canvas-inner .imp-note p + p{margin-top:12px}
.canvas-inner .imp-note p.imp-q{font-size:20px;font-weight:700;color:#0A1E42;line-height:1.4}
.imp-figure{display:flex;align-items:baseline;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid #EDF0F5}
.imp-figure .n{font-size:32px;font-weight:800;letter-spacing:-.02em;color:#1E59C7;line-height:1}
.imp-figure .t{font-size:14px;color:#6B7280}

/* --- 03 / The solution: a strategy statement, then four decisions.
   Screenshots run the full width of the frame — the product UI is the strongest
   asset in this case, and it has to be inspectable without squinting. --- */
.strategy{margin-top:30px;padding:24px 26px;border-radius:10px;background:#F5F8FE;border:1px solid #D3E0F8}
.strategy-label{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:#1E59C7;margin-bottom:12px}
.canvas-inner .strategy p{margin:0;font-size:16px;line-height:1.65;color:#4B5563;max-width:none}
.canvas-inner .strategy p.strategy-lead{font-size:24px;font-weight:700;line-height:1.35;
  letter-spacing:-.01em;color:#0A1E42;margin-bottom:12px}

.dec{margin-top:52px}
.dec-head{display:block}
/* Sub-sections used to lead with a numbered badge ("01", "02"...) in its own
   flex column, which pushed the heading and body text 54px right of every
   other paragraph in the case — the badge column plus its gap. That read as
   the text being misaligned against the rest of the page. Replaced with a
   left accent rule sitting flush against the copy's own edge (18px in, not
   54px), coloured with the case's own accent so the "this is a sub-point"
   signal survives without an indent. */
.dec-copy{min-width:0;border-left:3px solid var(--fg);padding-left:18px}
.dec-title{font-size:24px;line-height:1.2;font-weight:700;letter-spacing:-.01em;color:#0A1E42;margin:0 0 12px}
.dec-covers{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:14px}
.dec-covers span{font-size:12px;font-weight:600;padding:4px 10px;border-radius:20px;background:#EEF2F9;color:#0A1E42}
.canvas-inner .dec-copy p{margin:0;font-size:16px;line-height:1.72;color:#374151;max-width:none}

.dec-fig{margin:22px 0 0}
/* A before/after belongs side by side — the comparison is the point, and at half
   width each frame is still large enough to read the column set and controls. */
.dec-pair{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;align-items:start}
.dec-pair .dec-fig{margin-top:22px;min-width:0}
.dec-fig figcaption{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:#6B7280;margin-bottom:10px;line-height:1.45}
/* Every caption here is a short one-liner, so reserving two lines' height
   left a visible gap of dead air between the caption and its image. Down to
   one line's worth — still a floor if a caption ever runs long enough to
   wrap, just not a permanent empty second line when it doesn't. */
.dec-pair .dec-fig figcaption{min-height:1.45em}
.dec-fig .case-image{margin-top:0}

/* Ask AI as a sequence: intent in, table operation out, reader never leaves. */
.aiflow{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-top:22px}
.aiflow-step{min-width:0;padding:16px 18px;border-radius:10px;background:#FFFFFF;
  border:1px solid #E5E7EB;border-top:3px solid #3873E1}
.aiflow-k{font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:#1E59C7;margin-bottom:8px}
.canvas-inner .aiflow-step p{margin:0;font-size:14px;line-height:1.55;color:#4B5563;max-width:none}

/* A subheading inside a case section, for when one section carries two pieces
   of work (the input analysis and the market scan both live in Research). */
.canvas-inner.case-cockpit .refl-num,
.canvas-inner.case-cockpit .refl-title,
.canvas-inner.case-cockpit .cast-avatar,
.canvas-inner.case-cockpit .cast-role,
.canvas-inner.case-cockpit .cast-area,
.canvas-inner.case-cockpit .pshot-cap,
.canvas-inner.case-cockpit .pshot-pin,
.canvas-inner.case-cockpit .pshot-n,
.canvas-inner.case-cockpit .strategy-label,
.canvas-inner.case-cockpit .dec-title,
.canvas-inner.case-cockpit .dec-num,
.canvas-inner.case-cockpit .dec-covers span,
.canvas-inner.case-cockpit .dec-fig figcaption,
.canvas-inner.case-cockpit .aiflow-k,
.canvas-inner.case-cockpit .case-subhead,
.canvas-inner.case-cockpit .ev2-topic,
.canvas-inner.case-cockpit .ev2-who,
.canvas-inner.case-cockpit .ev2-label,
.canvas-inner.case-cockpit .imp-label,
.canvas-inner.case-cockpit .hypo-label,
.canvas-inner.case-cockpit .pain-list li,
.canvas-inner.case-cockpit .pain-list strong,
.canvas-inner.case-cockpit .cast-behaviour,
.canvas-inner.case-cockpit .cast-widgets{font-family:'Roboto','Space Grotesk',sans-serif}

.canvas-inner .case-subhead{font-size:20px;font-weight:700;letter-spacing:-.01em;
  color:#0A1E42;margin:38px 0 12px}

/* --- 03 / Research: competitive position read as a spec sheet.
   Four banded groups carry the SWOT; the "This list" column is tinted the way a
   spec comparison highlights the model you are actually looking at. --- */



/* --- 05 / Reflection: four takeaways, as cards rather than a long list --- */
.refl{display:flex;flex-direction:column;gap:10px;margin-top:28px}
.refl-card{display:flex;gap:14px;align-items:flex-start;min-width:0;
  padding:17px 20px;border-radius:10px;background:#FFFFFF;border:1px solid #E5E7EB}
.refl-num{flex:none;font-family:ui-monospace,'Roboto Mono',monospace;font-size:12px;font-weight:700;
  letter-spacing:.04em;color:#1E59C7;background:#E9EFFC;border-radius:6px;padding:4px 9px;margin-top:1px}
.refl-body{min-width:0}
.refl-title{font-size:16px;font-weight:700;color:#0A1E42;line-height:1.35;margin-bottom:4px}
.canvas-inner .refl-card p{margin:0;font-size:14px;line-height:1.55;color:#6B7280;max-width:none}

/* --- 01 / Problem: the six roles as people rather than data cards. An avatar and
   a stated need, no box around each one. --- */
.cast{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:28px 26px;margin-top:28px}
.cast-person{display:flex;gap:14px;min-width:0}
.cast-avatar{flex:none;width:42px;height:42px;border-radius:50%;color:#fff;
  font-size:14px;font-weight:700;letter-spacing:.03em;line-height:1;
  display:flex;align-items:center;justify-content:center}
.cast-body{min-width:0}
.cast-role{font-size:16px;font-weight:700;color:#0A1E42;line-height:1.3}
.cast-area{font-size:12px;font-weight:600;letter-spacing:.03em;color:#6B7280;margin-top:4px}
/* ---- Cockpit "who it's for": a roster, not five columns ----------------
   Five roles × (need + widgets + behaviour) is tabular content. Across five
   columns each cell had a ~200px measure — one sentence broke over four lines,
   three type treatments stacked, the widget line interrupted the thought
   mid-way, and the five columns ended at five different heights.
   As rows each role gets the full width: role, need, and behaviour sit in
   three aligned columns at a readable measure, and the baseline grid comes
   free. Same left-rule-and-hairline idiom as the precedence list in 03, so the
   two structural blocks in this case read as one family.
   A modifier, not a case-id selector: case-e2e also carries case-cockpit and
   shares this component for its six-person cast, which stays a grid. */
.cast.roster{display:block;margin-top:24px;border-top:1px solid #E8EDF6}
.cast.roster .cast-person{
  display:grid;
  grid-template-columns:214px minmax(0,1.02fr) minmax(0,1fr);
  gap:0 30px;align-items:start;
  padding:17px 10px 18px 4px;
  border-bottom:1px solid #E8EDF6;
  transition:background .15s ease;
}
/* the section itself is closed by .case-section's top border, so the last row
   would otherwise sit on a doubled rule */
.cast.roster .cast-person:last-child{border-bottom:none;padding-bottom:2px}
/* scanning aid, not decoration: five near-identical rows are easier to hold
   your place in when the one under the cursor separates from its neighbours */
.cast.roster .cast-person:hover{background:#F7F9FE}
.cast.roster .cast-id{display:flex;align-items:center;gap:11px;min-width:0}
/* 42px was sized for a column head; at row scale it competes with the prose */
.cast.roster .cast-avatar{width:30px;height:30px;font-size:12px}
.cast.roster .cast-role{font-size:16px;line-height:1.25}
.cast.roster .cast-need{min-width:0}
.canvas-inner .cast.roster .cast-need p{margin:0;font-size:16px;line-height:1.6;color:#374151}
/* the widget names sit under the need they answer, as tags rather than a line
   of blue prose — they are things in the product, not part of the sentence */
.cast.roster .cast-widgets{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.cast.roster .cast-widgets span{
  font-size:12px;font-weight:600;letter-spacing:.01em;
  color:#1E59C7;background:#EDF2FC;border-radius:5px;padding:3px 8px;
}
.canvas-inner .cast.roster p.cast-behaviour{margin:0;font-size:14px;line-height:1.6;color:#6B7280}
@media (max-width:900px){
  .cast.roster .cast-person{grid-template-columns:1fr;gap:10px}
}
.canvas-inner .cast-person p{margin:9px 0 0;font-size:14px;line-height:1.55;color:#4B5563;max-width:none}

/* --- 01 / Problem: the legacy list, annotated. Pins are positioned as
   percentages so they stay on target as the image scales. --- */
.pshot{margin-top:38px}
.pshot-cap{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#6B7280;margin-bottom:10px}
.pshot-frame{position:relative;line-height:0;border:1px solid #E5E7EB;border-radius:10px;overflow:hidden;background:#fff}
.pshot-frame img{width:100%;height:auto;display:block;border-radius:9px}
.pshot-pin{position:absolute;transform:translate(-50%,-50%);width:26px;height:26px;border-radius:50%;
  background:#3873E1;color:#fff;font-size:12px;font-weight:700;line-height:1;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 0 0 3px rgba(255,255,255,.92),0 2px 10px rgba(10,30,66,.30);z-index:2}
.pshot-key{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:18px;margin-top:20px}
.pshot-item{display:flex;gap:10px;min-width:0}
.pshot-n{flex:none;width:22px;height:22px;border-radius:50%;background:#E9EFFC;color:#1E59C7;
  font-size:12px;font-weight:700;line-height:1;display:flex;align-items:center;justify-content:center;margin-top:2px}
.canvas-inner .pshot-item p{margin:0;font-size:14px;line-height:1.55;color:#4B5563;max-width:none}

/* --- 02 / Research: an insight stated plainly. A rule rather than a tint, so
   it reads as emphasis instead of a marketing panel. --- */
.insight{margin-top:26px;padding-left:18px;border-left:3px solid #3873E1}
.canvas-inner .insight p{margin:0;font-size:16px;line-height:1.62;color:#6B7280;max-width:760px}
.canvas-inner .insight p.insight-lead{font-size:24px;font-weight:700;line-height:1.35;
  letter-spacing:-.01em;color:#0A1E42;margin-bottom:9px}

/* Evidence cards: the quote is secondary to the need it revealed. */
.ev2-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;margin-top:22px;align-items:start}
.ev2{min-width:0;padding:20px 22px;border:1px solid #E5E7EB;border-radius:10px;background:#FFFFFF}
.ev2-head{display:flex;align-items:center;gap:10px;margin-bottom:13px;flex-wrap:wrap}
.ev2-num{font-family:ui-monospace,'Roboto Mono',monospace;font-size:12px;font-weight:700;color:#9CA3AF}
.ev2-topic{font-size:14px;font-weight:700;color:#0A1E42}
.ev2-who{font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:#1E59C7;background:#E9EFFC;border-radius:20px;padding:3px 10px;margin-left:auto}
.ev2-quote{margin:0 0 15px;padding:0;font-size:14px;line-height:1.6;color:#9CA3AF;font-style:italic}
.ev2-label{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#1E59C7;margin-bottom:7px}
.canvas-inner .ev2 p{margin:0;font-size:16px;line-height:1.6;color:#0A1E42;max-width:none}

/* One-line summary under the section heading */
.cs-lede{font-size:20px;line-height:1.6;color:#0A1E42;font-weight:500;max-width:none}

/* Before / after comparison with labelled columns and decision notes */
.ba-compare{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px;margin-top:28px;align-items:start}
.ba-col{min-width:0}
.ba-label{
  display:inline-block;margin-bottom:10px;
  font-family:ui-monospace,'Roboto Mono',monospace;font-size:12px;font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;border-radius:20px;padding:4px 12px;
}
.ba-label.before{color:#8A6D3B;background:#FBF3E4}
.ba-label.after{color:#1E59C7;background:#E9EFFC}
.ba-shot{border:1px solid #E5E7EB;border-radius:10px;overflow:hidden;background:#fff}
.ba-shot img{width:100%;height:auto;display:block}
.ba-notes{margin:14px 0 0;padding-left:20px}
.ba-notes li{font-size:14px;line-height:1.6;color:#6B7280;margin-bottom:6px}
@media (max-width:880px){.ba-compare{grid-template-columns:1fr}}

/* Annotated figure — numbered decisions beside a screenshot */

/* Compact evidence pair — the quote does the work, the screenshot is proof */
.ev-mini-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;margin-top:22px;align-items:start}
.ev-mini{
  min-width:0;padding:20px 20px 18px;border-radius:12px;
  background:#FFFFFF;border:1px solid #E5E7EB;border-left:3px solid #3873E1;
}
.ev-mini .ev-head{margin-bottom:12px}
.ev-mini .ev-who{font-size:16px}
.ev-mini .ev-quote{
  margin:0 0 12px;padding:12px 14px;font-size:14px;line-height:1.55;
  border-left:2px solid #D3E0F8;background:#F5F8FE;border-radius:0 6px 6px 0;
  color:#14504A;font-style:italic;
}
.canvas-inner .ev-mini p.ev-mini-note{margin:0 0 14px;font-size:14px;line-height:1.6;color:#6B7280}
.ev-mini-shot{border:1px solid #E5E7EB;border-radius:8px;overflow:hidden;background:#fff}
.ev-mini-shot img{width:100%;height:auto;display:block}
@media (max-width:880px){.ev-mini-grid{grid-template-columns:1fr}}

.ev-head{display:flex;align-items:center;gap:10px;margin-bottom:14px;flex-wrap:wrap}
.ev-who{font-size:20px;font-weight:700;color:#0A1E42;letter-spacing:-.01em}
.ev-tag{font-family:ui-monospace,'Roboto Mono',monospace;font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#1E59C7;background:#E9EFFC;border-radius:20px;padding:4px 11px}
.ev-quote{
  margin:0 0 12px;padding:14px 18px;
  border-left:3px solid #D3E0F8;background:#F5F8FE;border-radius:0 8px 8px 0;
  font-size:16px;line-height:1.65;color:#14504A;font-style:italic;
}

/* Before / after comparison table */
.ba-table{margin-top:26px;border:1px solid #E5E7EB;border-radius:12px;overflow:hidden;background:#fff}
.ba-head,.ba-row{display:grid;grid-template-columns:150px minmax(0,1fr) minmax(0,1fr);gap:18px;padding:13px 20px;align-items:start}
.ba-row.two{grid-template-columns:150px minmax(0,1fr)}
.ba-head{background:#F7F9FA;border-bottom:1px solid #E5E7EB}
.ba-head span{font-family:ui-monospace,'Roboto Mono',monospace;font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#9CA3AF}
.ba-row{border-bottom:1px solid #F0F2F6;font-size:14px;line-height:1.55}
.ba-row:last-child{border-bottom:0}
.ba-k{font-weight:700;color:#0A1E42}
.ba-before{color:#9AA1AC}
.ba-before.wide{color:#374151}
.ba-after{color:#1E59C7;font-weight:500}
.ba-table.compact .ba-row{padding:11px 20px}
@media (max-width:820px){
  .ba-head{display:none}
  .ba-row,.ba-row.two{grid-template-columns:1fr;gap:5px}
  .ba-after::before{content:"After: ";color:#9CA3AF;font-weight:400}
  .ba-before::before{content:"Before: ";color:#9CA3AF}
}

/* inline chip row (relative date presets) */

/* Numbered rules list (Cockpit case) */
.ck-rules{display:flex;flex-direction:column;gap:9px;margin-top:20px}
.ck-rule{display:flex;gap:14px;align-items:flex-start;padding:15px 18px;border-radius:10px;background:#F7F9FD;border:1px solid #E5E7EB}
.ck-rule-num{flex:none;font-family:ui-monospace,'Roboto Mono',monospace;font-size:12px;font-weight:700;color:#1E59C7;background:#E9EFFC;border-radius:6px;padding:3px 8px;margin-top:1px}
.ck-rule-title{font-size:14px;font-weight:700;color:#0A1E42;margin-bottom:3px}
.ck-rule-desc{font-size:14px;line-height:1.55;color:#6B7280}
/* takeaways variant — sits on white, slightly roomier */
.ck-rules.learned{margin-top:26px;gap:10px}
.ck-rules.learned .ck-rule{background:#FFFFFF;padding:17px 20px}
.ck-rules.learned .ck-rule-title{font-size:16px}

/* Compact variant — the same complaint as the layout hierarchy: three cards
   for three one-line rules read heavier than the content needs. Reuses the
   .ck-layers left-rule treatment rather than adding a third pattern, and the
   prose still says "the second rule" / "the third rule", so order stays an <ol>. */
.ck-rules.compact{display:block;list-style:none;margin:20px 0 0;padding:0 0 0 18px;border-left:2px solid #D3E0F8}
.ck-rules.compact .ck-rule{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;padding:7px 0;background:none;border:none;border-radius:0}
.ck-rules.compact .ck-rule + .ck-rule{border-top:1px solid #EDF1F9}
.ck-rules.compact .ck-rule-num{background:none;padding:0;margin-top:0}
.ck-rules.compact .ck-rule-title{margin-bottom:0}
.ck-rules.compact .ck-rule-desc{flex:1 1 260px;min-width:0}
.ck-rules.compact .ck-rule-desc::before{content:"— "}

/* Role personas (Cockpit case) */

/* Sees / opens / acts flow (Cockpit case) */

/* "next release" variant of the approach card */

/* Widget catalogue */

/* Wireframe showcase — blueprint/sketch style, distinct from the final-product cards (Haus case) */
.wireframe-showcase{column-count:2;column-gap:20px;margin-top:28px}
.wireframe-shot{break-inside:avoid;margin-bottom:20px;border-radius:10px;overflow:hidden;background:#F4F4F1;border:1px dashed #9AA0AE}
.wireframe-shot-frame{max-height:420px;overflow:hidden;filter:grayscale(1) contrast(1.02)}
.wireframe-shot-frame img{width:100%;height:auto;display:block;object-fit:cover;object-position:top;opacity:.9}
.wireframe-shot-label{display:flex;align-items:center;gap:8px;padding:10px 14px;font-size:12px;font-weight:600;letter-spacing:.02em;color:#5B6478;background:#EDEEEA;border-top:1px dashed #9AA0AE}
.wireframe-shot-num{font-family:'Space Grotesk',monospace;font-size:12px;color:#9AA0AE;border:1px solid #9AA0AE;border-radius:4px;padding:1px 6px}
@media (max-width:800px){.wireframe-showcase{column-count:1}}

.case-image-glimpse{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin-top:24px}
.case-image-glimpse.two-up{grid-template-columns:repeat(2,minmax(0,1fr))}
.glimpse-col{min-width:0}
.glimpse-thumb{height:180px;border-radius:10px;overflow:hidden;background:transparent}
.glimpse-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.case-image-glimpse.two-up .glimpse-thumb{height:260px}
.glimpse-heading{margin-bottom:8px;font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--dim)}

.case-image-glimpse.style-tile-grid{grid-template-columns:repeat(5,minmax(0,1fr))}
.case-image-glimpse.style-tile-grid .glimpse-thumb{height:150px;background:var(--soft);border:1px solid var(--wline)}
.case-image-glimpse.style-tile-grid .glimpse-thumb img{object-fit:contain}
@media (max-width:900px){.case-image-glimpse.style-tile-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* Style tile — 2 per row, heading + description + full uncropped image (Haus case) */
.tile-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px;margin-top:28px;align-items:start}
.tile-item{display:flex;flex-direction:column;min-width:0;background:#fff;border:1px solid var(--wline);border-radius:14px;overflow:hidden}
.tile-copy{padding:20px 22px 16px}
.tile-title{font-size:16px;font-weight:700;color:var(--ink);letter-spacing:-.01em;margin-bottom:7px}
.tile-desc{margin:0;font-size:14px;line-height:1.62;color:var(--dim)}
.tile-shot{padding:0 16px 16px;background:#fff}
.tile-shot img{display:block;width:100%;height:auto;border-radius:8px;border:1px solid #EFEADB;background:#fff}
/* odd item out spans the full row so it never sits alone at half width */
.tile-grid .tile-item:last-child:nth-child(odd){grid-column:1 / -1}
.tile-grid .tile-item:last-child:nth-child(odd){flex-direction:row;align-items:center;gap:8px}
.tile-grid .tile-item:last-child:nth-child(odd) .tile-copy{flex:0 0 34%;padding:24px 8px 24px 24px}
.tile-grid .tile-item:last-child:nth-child(odd) .tile-shot{flex:1 1 auto;min-width:0;padding:16px}
@media (max-width:880px){
  .tile-grid{grid-template-columns:1fr}
  .tile-grid .tile-item:last-child:nth-child(odd){flex-direction:column}
  .tile-grid .tile-item:last-child:nth-child(odd) .tile-copy{flex:none;padding:20px 22px 16px}
  .tile-grid .tile-item:last-child:nth-child(odd) .tile-shot{padding:0 16px 16px}
}

/* The Brief card (Haus case) */
.brief-card{margin-top:28px;padding:26px 28px;border-radius:14px;background:#FFFDF7;border:1px solid var(--wline)}
.brief-card-label{font-family:'Space Grotesk',sans-serif;font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--fg);margin-bottom:18px}
.brief-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:22px 28px}
.brief-grid .k{font-size:16px;font-weight:700;color:var(--ink);margin-bottom:5px}
.brief-grid .v{font-size:14px;line-height:1.6;color:var(--dim)}
@media (max-width:760px){.brief-grid{grid-template-columns:1fr}}

/* Brand personality competitor grid (Haus case) */
.bp-grid{display:flex;flex-wrap:wrap;gap:14px;margin-top:28px}
.bp-card{flex:1;min-width:170px;border:1px solid var(--wline);border-radius:12px;overflow:hidden;background:var(--soft);text-align:center}
.bp-logo{height:110px;display:flex;align-items:center;justify-content:center;padding:16px}
.bp-logo img{max-width:78%;max-height:72%;object-fit:contain}
.bp-trait{padding:12px 12px 2px;font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink);border-top:1px solid var(--wline)}
.bp-desc{padding:4px 12px 16px;font-size:12px;line-height:1.5;color:var(--dim)}

/* Design direction card (Haus case) */
.dd-card{
  margin-top:32px;border-radius:16px;overflow:hidden;
  background:linear-gradient(160deg,#0F2340 0%,#17223B 55%,#1C2B47 100%);
  box-shadow:0 18px 40px -12px rgba(10,25,50,.35);
}
.dd-head{padding:26px 30px 22px;border-bottom:1px solid rgba(255,255,255,.09)}
.dd-eyebrow{
  display:inline-flex;align-items:center;gap:9px;
  font-family:'Space Grotesk',sans-serif;font-size:12px;font-weight:700;
  letter-spacing:.11em;text-transform:uppercase;color:#F2C14E;
}
.dd-eyebrow::before{content:"";width:20px;height:2px;background:#F2C14E;border-radius:2px}
.dd-lead{margin:12px 0 0;max-width:620px;font-size:14px;line-height:1.65;color:rgba(255,255,255,.62)}
.dd-rows{display:flex;flex-direction:column}
.dd-row{
  display:grid;
  grid-template-columns:44px 168px minmax(0,1fr) auto;
  align-items:center;gap:18px;
  padding:17px 30px;
  border-bottom:1px solid rgba(255,255,255,.07);
  transition:background .16s ease;
}
.dd-row:last-child{border-bottom:0}
.dd-row:hover{background:rgba(255,255,255,.035)}
.dd-num{
  font-family:ui-monospace,'Roboto Mono',monospace;font-size:12px;font-weight:700;
  color:#F2C14E;background:rgba(242,193,78,.13);
  border-radius:6px;padding:4px 0;text-align:center;letter-spacing:.02em;
}
.dd-k{font-size:12px;font-weight:700;letter-spacing:.075em;text-transform:uppercase;color:rgba(255,255,255,.5)}
.dd-v{font-size:14px;font-weight:600;color:#fff;line-height:1.45}
.dd-extra{display:flex;align-items:center;gap:12px;justify-self:end}
.dd-swatches{display:flex;gap:8px}
.dd-sw{display:flex;align-items:center;gap:6px}
.dd-sw-chip{width:17px;height:17px;border-radius:5px;flex:none;box-shadow:inset 0 0 0 1px rgba(255,255,255,.22)}
.dd-sw-hex{font-family:ui-monospace,'Roboto Mono',monospace;font-size:12px;color:rgba(255,255,255,.5);letter-spacing:.01em}
.dd-specimen{
  font-family:'Poppins','Space Grotesk',sans-serif;font-size:24px;font-weight:600;line-height:1;
  color:#F2C14E;padding:3px 12px;border:1px solid rgba(242,193,78,.32);border-radius:8px;
}
@media (max-width:820px){
  .dd-row{grid-template-columns:38px minmax(0,1fr);gap:10px 14px;padding:16px 20px}
  .dd-k{grid-column:2}
  .dd-v{grid-column:2}
  .dd-extra{grid-column:2;justify-self:start;margin-top:4px}
  .dd-head{padding:22px 20px 18px}
}

.bp-banner{margin-top:28px;background:var(--ink);color:#fff;border-radius:14px;padding:28px 32px}
.bp-banner-label{font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:rgba(255,255,255,.55);margin-bottom:18px}
.bp-banner-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:22px}
.bp-banner-grid .k{font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:rgba(255,255,255,.55);margin-bottom:6px}
.bp-banner-grid .v{font-size:14px;font-weight:600;color:#fff;line-height:1.45}

.outcomes-grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:18px;margin-top:22px}
.outcome-card{padding:26px;border:1px solid var(--wline);border-radius:14px;background:var(--soft)}
.outcome-card .val{font-size:32px;font-weight:800;letter-spacing:-.02em;color:var(--fg)}
.canvas-inner.case-dark .outcome-card .val{color:#FF5C4D}
.outcome-card .lbl{font-size:14px;color:var(--dim);margin-top:6px}

/* ---- Next case study strip (replaces the old "back to all projects" /
   "get in touch" CTA row at the end of a case) ---- */
.next-strip{
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  margin-top:28px;padding:26px 28px;border-radius:14px;
  border:1px solid var(--wline);background:var(--soft);
  transition:border-color .18s ease;
}
.next-strip:hover{border-color:var(--fg)}
.next-strip-copy{display:flex;flex-direction:column;gap:8px;min-width:0}
.next-strip-label{font-size:11px;font-weight:700;letter-spacing:.1em;color:var(--dim)}
.next-strip-title{
  font-size:24px;font-weight:600;letter-spacing:-.01em;color:var(--ink);
  font-family:'Sprat','Space Grotesk',sans-serif;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.next-strip-arrow{flex:none;color:var(--fg)}

/* ---- Footer copyright line, sitting below the last frame rather than
   inside it ---- */
.case-footer-copy{
  display:flex;justify-content:space-between;gap:16px;
  margin:0 4px 0;padding-bottom:48px;font-family:ui-monospace,'Roboto Mono',monospace;
  font-size:12px;letter-spacing:.02em;color:var(--dim,#5C5C66);
}
/* Home/Projects close on a bordered, shadowed .sheet rather than a flush
   .frames stack, so the signature line needs a little air above it instead
   of sitting flush against the card's shadow. */
.case-footer-copy.page-footer-copy{margin-top:20px}

/* Case study: conversational chat lives in the left rail; the canvas shows
   one big static preview of the project. */
.case-chat-feed{flex:1;overflow-y:auto;padding:4px 14px 10px}
.chat-msg{margin-bottom:14px;animation:fadeUp .4s ease both}
.chat-msg.bubble-row{margin-bottom:22px}
.chat-msg.plain{font-size:12px;font-weight:600;line-height:1.5;color:#fff;margin-bottom:4px}
.chat-msg.user.bubble-row{display:flex;align-items:flex-end;justify-content:flex-end;gap:8px;margin-left:auto;max-width:88%;width:fit-content}
.bubble-card.user-bubble{flex:none;background:#2A2A2E;color:#fff;border-radius:18px 18px 4px 18px;padding:10px 14px;font-size:12px;font-weight:600;text-align:left}

/* Small floating preview thumbnail above the summary bubble */
.case-thumb-float{position:relative;z-index:1;width:98px;margin:0 0 16px auto;border-radius:12px;overflow:hidden;box-shadow:0 10px 22px rgba(0,0,0,.35);border:1px solid #333338}
.case-thumb-float img{width:100%;height:64px;object-fit:cover;display:block}
.case-thumb-float.contain{background:#fff}
.case-thumb-float.contain img{height:64px;object-fit:contain}

/* Summary bubble — rounded chat bubble with the avatar sitting beside it
   (not overlapping), aligned to the bubble's bottom edge. */
.chat-msg.assistant.bubble-row{display:flex;align-items:flex-end;gap:8px;max-width:none}
.bubble-card{flex:1;min-width:0;background:#2A2A2E;border-radius:18px 18px 4px 18px;padding:18px 20px}
.chat-avatar{flex:none;width:28px;height:28px;border-radius:50%;object-fit:cover;border:2px solid #1B1B1E;box-shadow:0 2px 6px rgba(0,0,0,.4)}
.chat-msg.assistant.case-topic-card{background:#232326;border:1px solid #333338;border-radius:12px;padding:16px 16px;max-width:none;color:#D6D6DA}
.chat-msg.assistant.case-topic-card .case-eyebrow{margin-top:0;font-size:12px;color:#9A9AA2}
.chat-msg.assistant.case-topic-card h2{margin-top:8px;font-size:14px;line-height:1.35;color:#fff}
.chat-msg.assistant.case-topic-card p{margin-top:8px;font-size:12px;line-height:1.55;color:#B3B3BA;max-width:none}
.chat-msg.assistant.case-topic-card .case-quote{font-size:12px;padding:12px;margin-top:12px;background:#1A1A1D;color:#D6D6DA}
/* Rich multi-column blocks (built for a wide page) collapse to a single
   column so they stay legible in the narrow rail. */
.chat-msg.assistant.case-topic-card .who-grid,
.chat-msg.assistant.case-topic-card .outcomes-grid,
.chat-msg.assistant.case-topic-card .competitor-cols,
.chat-msg.assistant.case-topic-card .stat-strip{display:flex;flex-direction:column;gap:10px}
.chat-msg.assistant.case-topic-card .who-card,
.chat-msg.assistant.case-topic-card .outcome-card,
.chat-msg.assistant.case-topic-card .competitor-card{padding:12px;font-size:12px}
.chat-msg.assistant.case-topic-card .outcome-card .val{font-size:24px}
.chat-msg.assistant.case-topic-card .decision-row{grid-template-columns:28px 1fr;gap:10px;margin-top:10px}
.chat-msg.assistant.case-topic-card .decision-num{width:28px;height:28px;font-size:12px;border-radius:8px}
.chat-msg.assistant.case-topic-card .decision-title{font-size:12px}
.chat-msg.assistant.case-topic-card .decision-body{font-size:12px}
.chat-msg.assistant.case-topic-card .case-image,
.chat-msg.assistant.case-topic-card .problem-steps{margin-top:10px}
.chat-msg.assistant.case-topic-card .problem-step{padding:10px 12px;font-size:12px}

.ccard-title{margin-top:0;font-size:16px;font-weight:800;letter-spacing:-.02em;color:#fff}
.ccard-desc{margin-top:8px;font-size:12px;line-height:1.6;color:#D9D9DE;max-width:none}

.case-chat-suggestions{display:flex;flex-direction:column;align-items:flex-start;gap:5px;padding:2px 0 16px;overflow-y:auto}
.case-chip{width:auto;align-self:flex-start;text-align:left;padding:9px 14px;border-radius:8px;border:1px solid #2A2A2E;background:#1C1C1F;color:#D6D6DA;font-family:inherit;font-size:12px;font-weight:600;cursor:pointer;transition:background .15s ease,border-color .15s ease}
.case-chip:hover{background:#26262A;border-color:var(--fg);color:#fff}
.case-chip.active{background:#2A2A2E;border-color:var(--fg);color:#fff}
.case-chat-done{display:flex;flex-direction:column;gap:8px;width:100%}
.case-chat-done a{display:flex;align-items:center;justify-content:center;gap:7px;padding:11px 16px;border-radius:9px;font-size:12px;font-weight:600;text-decoration:none;transition:transform .2s ease}
.case-chat-done a.primary{background:var(--fg);color:#fff}
.case-chat-done a.primary:hover{transform:translateY(-2px)}
.case-chat-done a.secondary{border:1.5px solid #333338;color:#D6D6DA}

/* Composer pinned to the bottom of the rail, like a real chat input */
.case-chat-composer{
  position:sticky;bottom:0;flex:none;margin-top:auto;
  display:flex;align-items:center;gap:8px;
  padding:12px 14px;background:var(--c1);border-top:1px solid #2A2A2E;
}
.case-chat-composer input{
  flex:1;min-width:0;border:1px solid #2A2A2E;background:#1C1C1F;color:#fff;
  border-radius:999px;padding:9px 14px;font-family:inherit;font-size:12px;outline:0;
}
.case-chat-composer input::placeholder{color:#7A7A82}
.case-chat-composer input:focus{border-color:var(--fg)}
.case-composer-send{
  flex:none;width:30px;height:30px;border-radius:50%;border:0;background:var(--fg);color:#fff;
  display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s ease;
}
.case-composer-send:hover{background:#0b7fd4}
.case-chat-done a.secondary:hover{border-color:var(--fg);color:#fff}

/* Big static project preview in the main canvas */
.case-preview-sheet{padding:56px;display:flex;align-items:center;justify-content:center}
.case-preview-stage{width:100%;max-width:820px;text-align:center}
.case-preview-frame{width:100%;border-radius:16px;overflow:hidden;box-shadow:0 20px 50px -20px rgba(0,0,0,.3)}
.case-preview-frame img{width:100%;display:block}
.case-preview-caption{margin-top:16px;font-family:'Space Grotesk',sans-serif;font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:var(--dim)}

.problem-steps{display:flex;flex-direction:column;gap:10px;margin-top:20px}
.problem-step{display:flex;align-items:center;gap:16px;padding:16px 20px;border-radius:10px;background:rgba(255,255,255,.02);border:1px solid #22222A}
.problem-step.warn{background:rgba(255,92,77,.08);border-color:rgba(255,92,77,.25)}
.problem-step .num{flex:none;width:26px;height:26px;border-radius:50%;background:#3A3A44;color:#fff;font-size:12px;font-weight:700;display:flex;align-items:center;justify-content:center}
.problem-step.warn .num{background:#FF5C4D}
.problem-step .title{font-size:16px;font-weight:500;color:#fff}
.problem-step .sub{font-family:'Space Grotesk',sans-serif;font-size:12px;color:#6B6B76;margin-top:3px}
.problem-step.warn .sub{color:#FF7A6B}
.problem-box{margin-top:32px;border:1px solid #22222A;border-radius:14px;padding:28px;background:#0E0E13}
.problem-box-label{font-family:'Space Grotesk',sans-serif;font-size:12px;font-weight:700;letter-spacing:.1em;color:#7A7A85;margin-bottom:20px}

.stat-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:24px}
.stat-strip .stat{border:1px solid #22222A;border-radius:12px;padding:18px}
.stat-strip .stat .n{font-size:28px;font-weight:800;letter-spacing:-.02em;color:#FF5C4D}
.stat-strip .stat .t{font-size:14px;font-weight:600;color:#fff;margin-top:8px;line-height:1.35}
.stat-strip .stat .d{font-size:12px;color:#7A7A85;margin-top:6px;line-height:1.5}

.competitor-card{border:1px solid #22222A;border-radius:14px;padding:26px;background:#0E0E13;margin-top:16px}
.competitor-head{display:flex;gap:14px;align-items:flex-start}
.competitor-icon{flex:none;width:42px;height:42px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:20px}
.competitor-name{font-size:16px;font-weight:700;color:#fff}
.competitor-cat{font-size:14px;color:#7A7A85;margin-top:2px}
.competitor-cols{display:grid;grid-template-columns:1fr 1fr;gap:24px;margin-top:20px}
.competitor-cols .label{font-family:'Space Grotesk',sans-serif;font-size:12px;font-weight:700;letter-spacing:.08em;margin-bottom:10px}
.competitor-cols .strengths .label{color:#2ED573}
.competitor-cols .gaps .label{color:#FF5C4D}
.clist{display:flex;flex-direction:column;gap:8px}
.clist div{display:flex;gap:8px;font-size:14px;line-height:1.5;color:#B4B4BE}
.competitor-read{margin-top:20px;padding:16px 18px;border-radius:10px;background:rgba(255,255,255,.03);border:1px solid #22222A;font-size:14px;line-height:1.6;color:#9B9BA6}
.competitor-eco{margin-top:16px;font-family:'Space Grotesk',sans-serif;font-size:12px;color:#6B6B76}

/* ============================================================
   Responsive fallback — between 1180px and the mobile breakpoint
   below, the shell keeps its desktop layout and scrolls horizontally
   rather than breaking, matching how a real Figma canvas behaves at
   in-between viewport sizes (a small laptop window, a tablet in
   landscape).
   ============================================================ */
@media (max-width:1180px){
  body{overflow-x:auto}
}

/* ============================================================
   Mobile — the rail becomes an off-canvas drawer opened by a
   floating hamburger button, the right inspector disappears
   entirely (there's no room for a third column on a phone), and the
   shell drops its desktop min-width so it actually fits the
   viewport instead of forcing horizontal scroll. The canvas itself
   needs no special-casing here: fitHomeZoom() already scales the
   1280px frame down to whatever width is left (see ZOOM_MIN in
   script.js), and case-study content reflows via its own existing
   breakpoints.
   ============================================================ */
.mobile-menu-btn{display:none}
.rail-backdrop{display:none}
@media (max-width:768px){
  body{overflow-x:hidden}
  #shell{min-width:0}
  .inspector{display:none !important}

  /* Chrome bar: pull the search icon in from the far right edge — flex
     `order` (not a DOM move) so desktop's source order is untouched — and
     hand that corner to the new "Connect" button instead. Both keep their
     default order:0 so they still land after the traffic lights/home/tabs/+
     that come before them in markup; only search, the spacer, and connect
     get explicit values so they land search → (spacer fills the gap) →
     connect, left to right. */
  #tabSearchBtn{order:1}
  .chrome-spacer{order:2}
  .chrome-connect-wrap{display:flex;align-items:center;order:3}
  /* Anchored to the bar's right edge normally; on a narrow phone that can
     run past the left edge, so it floats free of any one button and just
     spans the bar with a margin instead. */
  .tab-search{left:10px;right:10px;width:auto}
  /* Decorative only (aria-hidden, no working controls) — not worth the 52px
     of a phone's width once the rail and inspector are already gone. */
  .iconstrip{display:none !important}

  .rail,
  .rail.case-mode{
    position:fixed;top:calc(var(--chrome-h) + var(--ruler-h));left:0;bottom:0;
    width:82vw;max-width:300px;z-index:210;
    transform:translateX(-100%);transition:transform .22s ease;
    box-shadow:16px 0 40px rgba(0,0,0,.35);
  }
  .rail.mobile-open{transform:translateX(0)}

  /* Moved down to the bottom-left, out of the hamburger's old spot above the
     chrome bar — a thumb-reachable corner, and it no longer needs to share
     that corner with the drawer's own header row once opened. */
  .mobile-menu-btn{
    display:flex;align-items:center;justify-content:center;
    position:fixed;left:16px;bottom:calc(16px + env(safe-area-inset-bottom));top:auto;
    width:46px;height:46px;border-radius:50%;border:0;cursor:pointer;
    background:#1E1E1E;color:#fff;box-shadow:0 8px 22px rgba(0,0,0,.35);
    z-index:220;
  }
  .mobile-menu-btn.on{background:var(--fg,#0D99FF)}

  .rail-backdrop{
    display:block;position:fixed;left:0;right:0;bottom:0;
    top:calc(var(--chrome-h) + var(--ruler-h));
    background:rgba(0,0,0,0);pointer-events:none;z-index:205;
    transition:background .22s ease;
  }
  .rail-backdrop.on{background:rgba(0,0,0,.42);pointer-events:auto}

  /* The "Minimize UI" affordance (and the floating mini-bars it summons) is
     a desktop concept with no equivalent on mobile — the rail is already a
     drawer and the inspector is already gone, so there's nothing left to
     minimize. Hiding the toggle avoids a dead end where minimizing leaves
     no way back in, since the mini-bars it would normally swap in are
     desktop-only real estate savers, not a mobile nav pattern. */
  .ui-toggle{display:none}
  #shell.ui-min .mini-bar{display:none}

  /* ===== Home on a phone: Home and Projects merged into one fluid feed —
     hero at the top, then every project as a full-width stacked card
     (thumbnail, heading, description, pills). Toggled by fitHomeZoom() in
     script.js, which also skips the scale-to-fit transform for this case;
     without both halves the 1280px frame would either overflow sideways
     (width alone) or stay a shrunk miniature (skipping the transform alone).
     Scoped under #shell.mobile-native-home so nothing here leaks into the
     Projects/About pages, which still use the scaled-frame approach. */
  #shell.mobile-native-home .canvas-inner{width:100%;margin:0;padding:0}
  #shell.mobile-native-home .canvas-wrap{padding:0}
  #shell.mobile-native-home .corner,
  #shell.mobile-native-home .ruler,
  #shell.mobile-native-home .crumb{display:none}
  #shell.mobile-native-home .sheet{border-radius:0;box-shadow:none;border:0}

  #shell.mobile-native-home .home-hero{
    padding:28px 20px 40px;min-height:0;display:block;
  }
  #shell.mobile-native-home .chat-hero{max-width:100%}
  #shell.mobile-native-home .chat-greeting{font-size:14px;margin-bottom:20px}
  #shell.mobile-native-home .ctx{font-size:clamp(30px,9vw,40px);white-space:normal}
  #shell.mobile-native-home .chat-line{gap:8px}
  #shell.mobile-native-home .logo-box-dark{width:64px;height:44px;border-radius:11px}
  #shell.mobile-native-home .word-rotator{height:18px}
  #shell.mobile-native-home .word-rotator .word{font-size:18px}
  #shell.mobile-native-home .chatbar{margin-top:28px}

  /* The carousel controls (arrows, "See more", hover-narration) stop making
     sense once every project is already stacked in view below — nothing
     left to scroll to or navigate away for. */
  #shell.mobile-native-home .examples-row{margin-top:36px}
  #shell.mobile-native-home .examples-nav{display:none}
  #shell.mobile-native-home .examples-label{font-size:15px}
  #shell.mobile-native-home .examples-track{
    display:flex;flex-direction:column;gap:20px;
    overflow:visible;padding-bottom:0;
  }
  #shell.mobile-native-home .example-card{flex:none;width:100%}
  #shell.mobile-native-home .example-card .ex-thumb{aspect-ratio:16/10}

  /* ===== "Expand" affordance on every case study screenshot — tapping opens
     the full-screen preview below (bindImageLightbox in script.js). The badge
     itself is a real element (enhanceCaseImagesMobile in script.js appends a
     .expand-badge into any .case-image/.glimpse-thumb that holds an <img>,
     which skips the autoplaying feature demo videos — a static "Expand" pill
     on a video that's already playing full-width wouldn't add anything). */
  .case-image:has(img),
  .case-image-glimpse .glimpse-thumb:has(img){position:relative;cursor:zoom-in}
  .expand-badge{
    display:inline-flex;align-items:center;gap:5px;
    position:absolute;top:10px;right:10px;z-index:2;
    background:rgba(20,20,22,.72);color:#fff;
    font-size:11px;font-weight:600;letter-spacing:.01em;
    padding:5px 10px;border-radius:999px;
    pointer-events:none; /* the tap target is the whole image, not just the pill */
  }
  .expand-badge svg{width:11px;height:11px;flex:none;display:block}
}

/* ===== Full-screen image preview (mobile only — see bindImageLightbox in
   script.js, which never opens this on a desktop-width viewport). Its markup
   sits outside #shell in index.html so this fixed overlay is anchored to the
   real viewport rather than to the canvas frame's own scale-to-fit transform. */
.img-lightbox{
  position:fixed;inset:0;z-index:300;
  background:rgba(18,18,20,.94);
  display:flex;align-items:center;justify-content:center;
  padding:28px;
}
.img-lightbox[hidden]{display:none}
.img-lightbox img{max-width:100%;max-height:100%;object-fit:contain;border-radius:10px;display:block}
.img-lightbox-close{
  position:fixed;top:16px;right:16px;z-index:301;
  width:40px;height:40px;border-radius:50%;border:0;cursor:pointer;
  background:#fff;color:#111;box-shadow:0 8px 22px rgba(0,0,0,.35);
  display:flex;align-items:center;justify-content:center;
}

/* ==========================================================================
   Haus — full, untrimmed imagery.
   Declared last, with specificity high enough to beat the shared component
   defaults (.case-image-glimpse.two-up .glimpse-thumb sets a 260px height at
   equal specificity, which previously won on source order and caused the
   image to overflow its box and overlap the following section).
   Scoped to .case-haus so the Cockpit showcase keeps its uniform tiles.
   ========================================================================== */
.canvas-inner.case-haus .case-image-glimpse.two-up .glimpse-thumb,
.canvas-inner.case-haus .case-image-glimpse .glimpse-thumb{
  height:auto;
  min-height:0;
  overflow:visible;
  background:transparent;
}
.canvas-inner.case-haus .case-image-glimpse.two-up .glimpse-thumb img,
.canvas-inner.case-haus .case-image-glimpse .glimpse-thumb img{
  width:100%;
  height:auto;
  object-fit:contain;
  display:block;
  border-radius:10px;
  border:1px solid var(--wline);
  background:#fff;
}
.canvas-inner.case-haus .case-image-glimpse{align-items:start}

/* Moodboard: smaller, and no box around it — the collage is already flattened
   onto the page background, so a border or panel would fight it. */
.canvas-inner.case-haus .case-image.contain.moodboard{
  max-width:660px;
  height:auto;
  margin-left:0;
  overflow:visible;
  background:transparent;
  border:0;
  padding:0;
}
.canvas-inner.case-haus .case-image.contain.moodboard img{border-radius:10px}

.canvas-inner.case-haus .wireframe-showcase .wireframe-shot-frame,
.canvas-inner.case-haus .product-showcase .product-shot-frame{
  max-height:none;
  height:auto;
  overflow:visible;
}
.canvas-inner.case-haus .wireframe-showcase .wireframe-shot-frame img,
.canvas-inner.case-haus .product-showcase .product-shot-frame img{
  width:100%;
  height:auto;
  object-fit:contain;
  object-position:top;
  display:block;
}
.canvas-inner.case-haus .wireframe-showcase,
.canvas-inner.case-haus .product-showcase{column-gap:24px}
.canvas-inner.case-haus .wireframe-shot,
.canvas-inner.case-haus .product-shot{margin-bottom:24px}

/* E2E: full, untrimmed UI screenshots. Declared last and with enough
   specificity to beat both the base .two-up 260px cap and the Haus overrides. */
.canvas-inner.case-e2e .case-image-glimpse.two-up .glimpse-thumb,
.canvas-inner.case-e2e .case-image-glimpse .glimpse-thumb{
  height:auto;min-height:0;overflow:visible;background:transparent;
}
.canvas-inner.case-e2e .case-image-glimpse.two-up .glimpse-thumb img,
.canvas-inner.case-e2e .case-image-glimpse .glimpse-thumb img{
  width:100%;height:auto;object-fit:contain;display:block;
  border:1px solid #E5E7EB;border-radius:8px;background:#fff;
}
.canvas-inner.case-e2e .case-image-glimpse{align-items:start}

/* ==========================================================================
   Logward palette (Tracking & Visibility case)

   The case carries .case-cockpit as well, for the Roboto typography and the
   never-crop-the-screenshot rules the two Shippeo cases already share. This
   block only re-tints: Voyager blue out, Logward orange in. Navy headings
   stay, because navy + orange is the product's own pairing — the sidebar is
   navy and every action in it is orange.

   Two oranges, deliberately. #F0661A is the product orange, used only for
   graphics (the eyebrow bar, large numerals) where contrast rules don't bite.
   --fg is the deeper #C2410C because --fg drives .case-tag at 12px and the
   white-on-accent primary button: white on #F0661A is 3.2:1 and fails, white
   on #C2410C is 5.2:1 and passes. Same reason every small label below uses it.
   ========================================================================== */
.canvas-inner.case-logward{--fg:#C2410C}
.canvas-wrap.case-fullbleed .canvas:has(.canvas-inner.case-logward){background:#FFFCFA}

.canvas-inner.case-logward .case-eyebrow.accent{color:#C2410C}
.canvas-inner.case-logward .case-eyebrow .bar{background:#F0661A}

.canvas-inner.case-logward .case-quote{
  border-left:3px solid #F0661A;
  background:#FFF6F0;
  color:#8A3A0B;
}

/* The card itself was still cockpit's cool #F9FAFB/#E5E7EB (inherited from
   the shared case-cockpit theme class) even though its badge/number chip
   was already orange — leaving the card read as blue against this case's
   warm page. .warn keeps its own higher-specificity red override below. */
.canvas-inner.case-logward .problem-step{background:#FFF7F1;border-color:#F9D9C2}
.canvas-inner.case-logward .problem-step .num{background:#FFF1E7;color:#C2410C}

.canvas-inner.case-logward .strategy{background:#FFF7F1;border-color:#F9D9C2}
.canvas-inner.case-logward .strategy-label{color:#C2410C}

.canvas-inner.case-logward .dec-num{background:#FFF1E7;color:#C2410C}
.canvas-inner.case-logward .dec-covers span{background:#FFF1E7;color:#9A3412}

.canvas-inner.case-logward .ck-rule{background:#FFF7F1;border-color:#F9D9C2}
.canvas-inner.case-logward .ck-rule-num{background:#FFF1E7;color:#C2410C}

.canvas-inner.case-logward .next-strip{background:#FFF7F1;border-color:#F9D9C2}

.canvas-inner.case-logward .imp-label{color:#C2410C}
.canvas-inner.case-logward .imp-figure .n{color:#F0661A}

/* ==========================================================================
   Projects list — hover preview as a themed product mockup

   A flat, saturated field in the project's own colour with a dark device on
   it. Two tablets, a laptop and a desktop monitor.

   UNIFORMITY IS THE POINT HERE. Every variant shows the screenshot at the
   same 340px width, and it is the SCREEN that is centred in the frame, not
   the device outline — stands and bases hang below it via position:absolute
   so they add no height to the centred box. Measured, the screen lands
   within 3px of the same spot in all four. One perspective, one tilt.
   If you add a variant, keep .pm-screen at 340px and hang any base off
   .pm-lid the same way, or the previews will jog as the cursor moves.

   Nothing is cropped by the frame — every device sits whole inside it.
   ========================================================================== */
.proj-hover-img{
  width:504px;height:360px;
  background:transparent;box-shadow:none;border-radius:0;overflow:visible;
}

.pm{
  position:absolute;inset:0;border-radius:14px;overflow:hidden;
  background:var(--field,#3B6FE0);
  box-shadow:0 0 0 1px rgba(0,0,0,.06),
             0 22px 44px -16px rgba(0,0,0,.34),
             0 50px 90px -34px rgba(0,0,0,.28);
}
/* one soft highlight, so a flat colour reads as a lit surface not a swatch */
.pm::before{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(125% 85% at 50% -8%, rgba(255,255,255,.17), transparent 62%);
}

.pm-stage{position:absolute;inset:0;perspective:1700px;perspective-origin:50% 50%}
.pm-dev{
  position:absolute;left:50%;top:50%;transform-style:preserve-3d;
  transform:translate(-50%,-50%) rotateX(3deg) rotateY(-8deg) rotateZ(-1.2deg);
}

/* the constant across every variant */
.pm-screen{position:relative;width:340px;aspect-ratio:16/10;border-radius:3px;overflow:hidden;background:#fff}
.pm-screen img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block}

.pm-lid{
  position:relative;background:linear-gradient(#2A2A31,#0E0E12);
  box-shadow:0 0 0 1px rgba(255,255,255,.13), 0 30px 56px -20px rgba(0,0,0,.55);
}
.pm-notch{
  position:absolute;top:0;left:50%;transform:translateX(-50%);z-index:2;
  width:74px;height:8px;border-radius:0 0 6px 6px;background:#0B0B0F;
}
.pm-cam{
  position:absolute;top:5px;left:50%;transform:translateX(-50%);z-index:2;
  width:4px;height:4px;border-radius:50%;background:#3A3B44;
}

/* ---- laptop ---- */
.mock-laptop .pm-lid{padding:10px 10px 12px;border-radius:12px 12px 3px 3px}
.pm-base{
  position:absolute;top:100%;left:50%;transform:translateX(-50%);
  width:396px;height:14px;border-radius:0 0 10px 10px;
  background:linear-gradient(#202026,#0A0A0E);
  box-shadow:0 14px 26px -10px rgba(0,0,0,.55);
}
.pm-base::after{content:'';display:block;width:74px;height:3px;margin:0 auto;
  border-radius:0 0 4px 4px;background:#33343C}

/* ---- desktop monitor ---- */
.mock-window .pm-lid{padding:9px 9px 15px;border-radius:9px}
.pm-neck{
  position:absolute;top:100%;left:50%;transform:translateX(-50%);
  width:48px;height:24px;background:linear-gradient(#23242B,#15161B);
  clip-path:polygon(16% 0,84% 0,100% 100%,0 100%);
}
.pm-foot{
  position:absolute;top:calc(100% + 24px);left:50%;transform:translateX(-50%);
  width:150px;height:8px;border-radius:4px;
  background:linear-gradient(#25262D,#101116);
  box-shadow:0 12px 22px -8px rgba(0,0,0,.55);
}

/* ---- tablet (Cockpit and Haus) ---- */
.mock-browser .pm-lid,
.mock-tablet  .pm-lid{padding:13px;border-radius:20px}
.mock-browser .pm-screen,
.mock-tablet  .pm-screen{border-radius:9px}

/* ---- the field colour per project ---- */
.mock-browser .pm{--field:#3B6FE0}   /* Cockpit    — Shippeo blue */
.mock-laptop  .pm{--field:#F0661A}   /* Tracking   — Logward orange */
.mock-window  .pm{--field:#4F46E5}   /* End-to-end — indigo */
.mock-tablet  .pm{--field:#D9A62B}   /* Haus       — gold */

/* ---- photo (Cockpit, Tracking, End-to-end) ----
   These screenshots are already a whole device shot on a desk, so the frame
   shows the photo itself rather than wrapping it in the CSS device chrome
   above — no field colour, no perspective stage, just the image, filled and
   cropped to the same 504x360 box every other variant uses. */
.mock-photo .pm.pm-photo{background:#000}
.pm-photo{overflow:hidden}
.pm-photo img{width:100%;height:100%;object-fit:cover;object-position:center 38%;display:block}


/* ==========================================================================
   Case study as a Figma canvas

   Each section is a frame sitting on the desk rather than a band in one long
   sheet, with its name above the top-left corner the way Figma labels an
   artboard. The names come from the case's own idx array, which also feeds
   the rail's frame list and the scroll-spy — one list, so the three cannot
   drift out of step.

   The per-case palettes still apply: the desk stays neutral grey and the
   FRAME takes the case's background, so a case reads as artwork on a canvas
   rather than a re-skinned page.
   ========================================================================== */
.canvas-wrap.case-canvas .canvas{background:var(--desk)}

.frames{display:flex;flex-direction:column;gap:72px;padding:14px 0 8px}

.fr{
  position:relative;
  background:#fff;
  border-radius:3px;
  box-shadow:0 1px 2px rgba(0,0,0,.05), 0 18px 44px -22px rgba(0,0,0,.22);
  transition:box-shadow .18s ease, outline-color .18s ease;
  outline:2px solid transparent;outline-offset:0;
}
/* the frame the reader is in — the rail already shows which frame is active,
   so the frame itself no longer draws a coloured selection stroke around it */

.fr-label{
  position:absolute;top:-21px;left:1px;
  display:flex;align-items:center;gap:6px;
  font-family:'Space Grotesk',system-ui,sans-serif;
  font-size:11.5px;font-weight:600;letter-spacing:.01em;
  color:#6B6B76;
  white-space:nowrap;
}
.fr.selected .fr-label{color:var(--fg)}

.fr-body{padding:64px}
/* The frame supplies the padding now, and the rule that used to separate one
   section from the next is what the frame boundary itself says. Both would
   otherwise show up as a stray line across the top of every frame. */
.fr-body > .section{padding:0}
.fr-body > .case-section{padding:0;border-top:0}

/* frame fill per case palette */
.canvas-inner.case-cockpit .fr{background:#FBFCFE}
.canvas-inner.case-logward .fr{background:#FFFCFA}
.canvas-inner.case-warm    .fr{background:#F5F0E4}
.canvas-inner.case-haus    .fr{background:#FAF6EC}
.canvas-inner.case-dark    .fr{background:#0B0B0F;
  box-shadow:0 1px 2px rgba(0,0,0,.3), 0 18px 44px -22px rgba(0,0,0,.55)}
.canvas-inner.case-dark .fr-label{color:#8A8A94}

/* ---- left rail: the frame index ---- */
.rail-frames{display:flex;flex-direction:column;gap:1px;margin-top:8px;max-height:none}
.rail-frame{
  display:flex;align-items:center;gap:9px;
  padding:6px 10px;border-radius:5px;cursor:pointer;
  font-size:12.5px;color:var(--t2);
  transition:background .12s ease,color .12s ease;
}
.rail-frame svg{flex:none;opacity:.65}
.rail-frame:hover{background:var(--c2);color:var(--tx)}
.rail-frame.active{background:var(--c2);color:var(--tx)}
.rail-frame.active svg{opacity:1;color:var(--fg)}



/* ==========================================================================
   About — side-by-side intro, and the tools marquee
   ========================================================================== */
/* copy first, photo second — the column widths follow the DOM order so the
   reading order and the visual order stay the same */
/* Title reads as a page heading here, not a centered banner like the
   Projects page's "Featured Case Studies" — left-aligned over the intro. */
.about-title{text-align:left}
/* Photo shows in full (no crop), so top-aligned rather than centred — the
   photo is a tall 3:4 portrait against three short paragraphs, and centring
   a much shorter block against it just pushes the text down into a band of
   empty space above it. Top-aligned, both start on the same line and any
   leftover air falls below the text instead, which reads as normal
   whitespace rather than a gap something is missing from. */
.about-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,360px);
  gap:56px;align-items:start;margin-bottom:8px}
.about-split .about-photo-top{height:auto;margin-bottom:0;display:block}
.about-split .about-photo-top img{width:100%;height:auto;object-fit:contain}
.about-split .about-text{max-width:none;padding-top:0}
@media (max-width:1100px){.about-split{grid-template-columns:1fr;gap:32px;align-items:start}}

/* The track holds the list twice and slides exactly one copy width, so the
   loop is seamless — the second copy is where the first started. Pulled up
   closer to the skills/experience row above — the old 52+30px gap read as a
   dead band before the carousel. */
.tools-strip{margin-top:20px;padding-top:20px;border-top:1px solid var(--wline)}
.tools-marq{margin-top:16px;overflow:hidden}
.tools-track{gap:0;animation-duration:34s;filter:none;opacity:1}
.tools-marq:hover .tools-track{animation-play-state:paused}
.tool-item{display:inline-flex;align-items:center;gap:10px;flex:none;
  margin-right:14px;padding:10px 18px;border-radius:999px;
  border:1px solid var(--wline);background:#fff;
  font-size:14px;font-weight:600;color:var(--ink);white-space:nowrap}
.tool-item svg{width:17px;height:17px;flex:none;display:block}
.tool-letter{width:17px;height:17px;flex:none;border-radius:5px;background:var(--ink);
  color:#fff;font-size:10px;font-weight:700;display:flex;align-items:center;justify-content:center}
