/* =============================================================================
   SubmitInMe · LARAVEL DEVELOPMENT
   A case-study page, not a services brochure.

   The whole page is built on one repeating unit: PROBLEM -> SOLUTION ->
   BENEFIT. It is used twice:
     · once looking backwards, on six applications we have delivered
     · once looking forwards, on the situation the visitor is probably in

   A fixed three-colour language carries it - problem (rose), solution (blue),
   benefit (emerald) - so a reader knows what they are looking at before they
   read a word. Outcome numbers are set in mono at display size, because the
   numbers are the argument.

   The six case studies sit behind a tab strip rather than stacked down the
   page: six full dossiers in a row is an unreadable amount of scrolling.

   External dependencies (declared in the page <head>, in this order):
     1. Tailwind Play CDN  -> layout / spacing / type utilities
     2. Lucide             -> <i data-lucide="..."> icons
     3. Google Fonts       -> Inter + IBM Plex Mono

   Shares no CSS with v1 (sim-shared.css / laravel-development.css).
   ============================================================================= */

/* -----------------------------------------------------------------------------
   1 · TOKENS
   -------------------------------------------------------------------------- */
:root {
    --b-50:#eff6ff;  --b-100:#dbeafe; --b-200:#bfdbfe; --b-300:#93c5fd;
    --b-400:#60a5fa; --b-500:#3b82f6; --b-600:#2563eb; --b-700:#1d4ed8;

    --ink-900:#0f172a; --ink-800:#1e293b; --ink-700:#334155; --ink-600:#475569;
    --ink-500:#64748b; --ink-400:#94a3b8; --ink-300:#cbd5e1;

    --surface:#ffffff; --surface-alt:#f8fafc; --surface-alt-2:#f1f5f9;
    --line:#e2e8f0; --line-soft:#f1f5f9;

    --navy-900:#070a24; --navy-800:#0a1038; --navy-700:#0b1220;

    /* the three-colour language of the page */
    --problem:#e11d48; --problem-bg:#fff1f2; --problem-line:#fecdd3;
    --solution:#2563eb; --solution-bg:#eff6ff; --solution-line:#bfdbfe;
    --benefit:#047857;  --benefit-bg:#ecfdf5;  --benefit-line:#a7f3d0;

    --whatsapp:#25d366;

    --r-sm:.5rem; --r-md:.75rem; --r-lg:1rem; --r-xl:1.25rem; --r-2xl:1.75rem;
    --r-pill:9999px;

    --sh-1:0 1px 2px rgba(15,23,42,.05);
    --sh-2:0 6px 18px -8px rgba(15,23,42,.14);
    --sh-3:0 24px 50px -30px rgba(15,23,42,.35);
    --sh-blue:0 14px 30px -12px rgba(37,99,235,.42);

    --ease:cubic-bezier(.16,1,.3,1);

    /* ---------------------------------------------------------------------
       DEPLOYMENT HOOK - height of the site's global fixed/sticky header.

       This page is built standalone, so it defaults to 0. When it is dropped
       into the production shell that has a fixed navbar, everything that pins
       to the top of the viewport (the case-study project bar, the case
       gallery, and every in-page anchor's scroll offset) reads this value, so
       nothing ends up hidden underneath the navbar.

       Set it ONCE, either way:
         a) put  data-site-header  on the global header element and the page
            script measures it, keeps it in sync on resize, and sets this; or
         b) hard-code it here, e.g.  --site-header: 72px;

       If the global header is static (scrolls away), leave this at 0.
       --------------------------------------------------------------------- */
    --site-header: 0px;
}

/* -----------------------------------------------------------------------------
   2 · BASE
   -------------------------------------------------------------------------- */
html { scroll-behavior: smooth; }
body {
    font-family:'Inter', system-ui, -apple-system, sans-serif;
    background: var(--surface);
    color: var(--ink-800);
    -webkit-font-smoothing: antialiased;
}
h1, h2 {
    font-family: Inter, sans-serif !important;
}
section[id], article[id] { scroll-margin-top: calc(var(--site-header) + 1.5rem); }
.mono { font-family:'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace; }

::selection { background: var(--b-200); color: var(--ink-900); }
::-webkit-scrollbar { width:8px; height:8px; }
::-webkit-scrollbar-track { background: var(--surface-alt); }
::-webkit-scrollbar-thumb { background: var(--ink-300); border-radius:99px; }
::-webkit-scrollbar-thumb:hover { background: var(--ink-400); }

a:focus-visible, button:focus-visible, [tabindex]:focus-visible {
    outline:2px solid var(--b-600); outline-offset:3px; border-radius: var(--r-sm);
}
.on-dark a:focus-visible, .on-dark button:focus-visible { outline-color: var(--b-400); }

.sr-only {
    position:absolute; width:1px; height:1px; padding:0; margin:-1px;
    overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}
.skip-link {
    position:absolute; left:1rem; top:-100px; z-index:200;
    background: var(--b-600); color:#fff; font-size:.8125rem; font-weight:600;
    padding:.65rem 1rem; border-radius: var(--r-md); transition: top .2s var(--ease);
}
.skip-link:focus { top:1rem; }

/* -----------------------------------------------------------------------------
   3 · BUTTONS
   -------------------------------------------------------------------------- */
.btn {
    display:inline-flex; align-items:center; justify-content:center; gap:.55rem;
    font-size:.875rem; font-weight:600; line-height:1;
    padding:1rem 1.6rem; border-radius: var(--r-md);
    border:1px solid transparent; white-space:nowrap;
    transition: background .2s var(--ease), border-color .2s var(--ease),
                box-shadow .25s var(--ease), transform .2s var(--ease), color .2s;
}
.btn svg { width:1.05rem; height:1.05rem; stroke-width:2; flex-shrink:0; }
.btn:active { transform: translateY(1px); }
.btn-sm { padding:.6rem 1rem; font-size:.8125rem; }

.btn-primary { background: linear-gradient(180deg, var(--b-500), var(--b-600)); color:#fff; box-shadow: var(--sh-blue); }
.btn-primary:hover { background: linear-gradient(180deg, var(--b-400), var(--b-500)); box-shadow:0 18px 34px -12px rgba(37,99,235,.55); }

.btn-outline { background: var(--surface); border-color: var(--line); color: var(--ink-800); box-shadow: var(--sh-1); }
.btn-outline:hover { border-color: var(--b-300); color: var(--b-700); background: var(--b-50); }

.btn-glass { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.24); color:#fff; }
.btn-glass:hover { background: rgba(255,255,255,.18); border-color: rgba(255,255,255,.4); }

.btn-wa { background: var(--whatsapp); color:#fff; box-shadow:0 12px 26px -12px rgba(37,211,102,.6); }
.btn-wa:hover { background:#1eb956; }
.btn-wa svg { width:1.15rem; height:1.15rem; }

/* -----------------------------------------------------------------------------
   4 · SECTION HEADINGS
   Headings are deliberately allowed to run the full width of the section and
   are sized from the viewport, so they land on one line on a desktop instead
   of breaking into two.
   -------------------------------------------------------------------------- */
.eyebrow {
    display:inline-flex; align-items:center; gap:.55rem;
    font-family:'IBM Plex Mono', ui-monospace, monospace;
    font-size:.6875rem; font-weight:500; letter-spacing:.14em; text-transform:uppercase;
    color: var(--b-700); background: var(--b-50); border:1px solid var(--b-100);
    padding:.45rem .85rem; border-radius: var(--r-pill); margin-bottom:1.1rem;
}
.eyebrow::before { content:""; width:.375rem; height:.375rem; border-radius:99px; background: var(--b-500); }
.on-dark .eyebrow { color: var(--b-300); background: rgba(59,130,246,.12); border-color: rgba(96,165,250,.24); }
.on-dark .eyebrow::before { background: var(--b-400); }

.h2 {
    font-size:clamp(1.75rem, 1.05rem + 1.85vw, 2.6rem);
    font-weight:700; letter-spacing:-.025em; color: var(--ink-900); line-height:1.14;
}
@media (min-width:1100px) { .h2 { white-space:nowrap; } }   /* one line on desktop */
.on-dark .h2 { color:#fff; }
.h2 .accent { color: var(--b-600); }
.on-dark .h2 .accent { color: var(--b-400); }
.lede { margin-top:.9rem; font-size:1rem; line-height:1.75; color: var(--ink-500); max-width:72ch; }
.on-dark .lede { color: rgba(203,213,225,.78); }

/* -----------------------------------------------------------------------------
   5 · HERO - banner as the background, ticker docked at the bottom.
   Height is content-driven (no forced viewport height), matching the hero
   pattern used on the rest of the site (e.g. wordpress-development.html).
   -------------------------------------------------------------------------- */
.hero {
    position:relative;
    display:flex; flex-direction:column;
    overflow:hidden;
    /* same navy wash + exact gradient stops as v1's hero-section, so the two
       pages read as the same header treatment. Height is left to content,
       not forced to the viewport, to stay consistent with the rest of the
       site's heroes. */
    background: linear-gradient(90deg, #061133 0%, #07133B 40%, #081742 100%);
}

/* The banner is set inline on the element, not here: a url() written in this
   file (or in a custom property declared here) resolves against the
   stylesheet's folder, which would look for the image inside assetsnew/css/.

   contain + center right, exactly as v1 frames it, so the whole diagram stays
   readable on the right instead of being cropped by a cover fill.

   These two layers live inside .hero-body, NOT inside .hero. With contain, the
   rendered size of the banner is set by the height of its box: spanning the
   whole hero would include the ticker strip, giving a taller box and a visibly
   larger image than v1. Scoping them to the body reproduces v1's box exactly. */
/* Soft blue glow behind the diagram. A drop-shadow filter on .hero-media
   itself doesn't work here: the image fills its box edge-to-edge (inset:0)
   and .hero-body/.hero both clip overflow, so the shadow has no room to
   spill into and is invisible. A separate gradient layer, sized within the
   box, avoids that. Sits behind .hero-media (z-index:0, painted first) and
   under .hero-veil, so it reads as light coming from behind the diagram. */
.hero-glow {
    position:absolute; inset:0; z-index:0; pointer-events:none;
    background: radial-gradient(640px 520px at 74% 46%, rgba(96,165,250,.45), transparent 62%);
    opacity:.7;
    transition: opacity .5s var(--ease);
}
.hero:hover .hero-glow { opacity:1; }

.hero-media {
    position:absolute; inset:0; z-index:0;
    background-size: contain;
    background-position: center right;
    background-repeat: no-repeat;
}
/* readable copy on the left, banner left alone on the right */
.hero-veil {
    position:absolute; inset:0; z-index:1;
    background: linear-gradient(105deg,
        rgba(7,14,30,.94) 0%,
        rgba(7,14,30,.90) 25%,
        rgba(7,14,30,.78) 50%,
        rgba(7,14,30,.45) 70%,
        rgba(7,14,30,.20) 85%,
        rgba(7,14,30,.10) 100%);
}
.hero-veil::after {
    content:""; position:absolute; left:0; right:0; bottom:0; height:120px;
    background: linear-gradient(to top, rgba(7,14,30,.5) 0%, transparent 100%);
}

/* Wider than the rest of the page on purpose: the hero copy sits close to the
   left edge, the way v1 does, rather than inside the 80rem content column. */
.hero-shell {
    width:100%; max-width:1760px; margin:0 auto;
    padding-left:1.5rem; padding-right:1.5rem;
}
@media (min-width:1024px) { .hero-shell { padding-left:4rem; padding-right:4rem; } }
@media (min-width:1536px) { .hero-shell { padding-left:6rem; padding-right:6rem; } }

.hero-body {
    position:relative; overflow:hidden;
    flex:1 1 auto; display:flex; align-items:center;
    padding:4.5rem 0;
}
.hero-body > .hero-shell { position:relative; z-index:2; }
.hero-foot { position:relative; z-index:2; flex:0 0 auto; }

.hero-badge {
    display:inline-flex; align-items:center; gap:.6rem;
    padding:.5rem .95rem; border-radius: var(--r-pill);
    background: rgba(59,130,246,.15); border:1px solid rgba(96,165,250,.25);
    font-family:'IBM Plex Mono', ui-monospace, monospace;
    font-size:.6875rem; font-weight:500; letter-spacing:.11em; text-transform:uppercase; color: var(--b-300);
}
.hero-badge .dot { position:relative; display:flex; width:.5rem; height:.5rem; }
.hero-badge .dot i, .hero-badge .dot b { position:absolute; inset:0; border-radius:99px; background: var(--b-400); }
.hero-badge .dot i { animation: ping 2s cubic-bezier(0,0,.2,1) infinite; }
@keyframes ping { 75%,100% { transform:scale(2.2); opacity:0; } }

.hero-h1 {
    font-size:clamp(2.1rem, 1.1rem + 3.6vw, 3.6rem);
    font-weight:800; letter-spacing:-.035em; line-height:1.08; color:#fff;
    max-width:22ch;
    text-shadow:0 2px 30px rgba(0,0,0,.5);
}
.hero-h1 em { font-style:normal; color: var(--b-400); }
.hero-sub {
    font-size:1.0625rem; line-height:1.8; color: rgba(219,234,254,.82); max-width:40rem;
    text-shadow:0 1px 12px rgba(0,0,0,.4);
}

/* -----------------------------------------------------------------------------
   6 · MARQUEE - the stack ticker docked to the base of the hero
   The track holds the item list twice; translating it -50% loops seamlessly.
   -------------------------------------------------------------------------- */
/* light band, same as v1's ticker strip */
.ticker { background:#f1f5f9; border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
.marquee {
    position:relative; overflow:hidden;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.marquee-track { display:flex; align-items:center; gap:.7rem; width:max-content; animation: mqSlide 48s linear infinite; }
.marquee:hover .marquee-track, .marquee:focus-within .marquee-track { animation-play-state: paused; }
@keyframes mqSlide { to { transform: translateX(-50%); } }

/* metrics match v1's ticker item exactly, so the strip is the same height and
   the hero box above it (and therefore the contained banner) matches v1 */
.mq-item {
    display:inline-flex; align-items:center; gap:.55rem; flex-shrink:0;
    padding:.6rem 1.1rem; border-radius: var(--r-pill);
    border:1px solid var(--line); background:#fff;
    color:#334155; font-size:.8125rem; font-weight:600; white-space:nowrap;
    box-shadow:0 1px 2px rgba(15,23,42,.04);
}
.mq-item img { width:1.15rem; height:1.15rem; object-fit:contain; }
.mq-item svg { width:1rem; height:1rem; color: var(--b-600); stroke-width:2; }

@media (prefers-reduced-motion: reduce) {
    .marquee-track { animation:none; }
    .marquee { overflow-x:auto; }
}

/* -----------------------------------------------------------------------------
   7 · CTA STRIP (sits directly under the hero) + BREADCRUMB
   -------------------------------------------------------------------------- */
.cta-strip {
    display:flex; flex-direction:column; align-items:center; gap:1.1rem;
    width:75%; margin:0 auto;
    text-align:center;
    background: linear-gradient(120deg, var(--b-50), #eef2ff 55%, #f5f3ff);
    border:1px solid var(--b-100);
    border-radius: var(--r-2xl);
    padding:2.75rem 3.5rem;
}
.cta-strip h2 { font-size:clamp(1.3rem, 1rem + 1vw, 1.75rem); font-weight:800; letter-spacing:-.02em; color: var(--ink-900); }
.cta-strip h2 span { color: var(--b-600); }
.cta-strip p { margin-top:.5rem; font-size:.9375rem; line-height:1.75; color: var(--ink-500); }
.cta-strip .flex-wrap { justify-content:center; }

.crumb {
    display:flex; align-items:center; flex-wrap:wrap; gap:.55rem;
    font-size:.8125rem; font-weight:500; color: var(--ink-500);
}
.crumb a { color: var(--ink-500); transition:color .2s; }
.crumb a:hover { color: var(--b-600); }
.crumb svg { width:.85rem; height:.85rem; color: var(--ink-300); }
.crumb [aria-current] { color: var(--ink-900); font-weight:600; }

/* -----------------------------------------------------------------------------
   8 · METHOD STRIP - teaches the reader how to read the rest of the page
   -------------------------------------------------------------------------- */
.method { --method-gap:1rem; display:grid; gap: var(--method-gap); }
@media (min-width:900px) { .method { --method-gap:2rem; grid-template-columns:repeat(3, minmax(0,1fr)); } }
.method-step {
    position:relative;
    border:1px solid var(--line); border-radius: var(--r-xl);
    padding:1.5rem 1.4rem; background: var(--surface);
    --tone: var(--ink-500);
}
.method-step.is-problem  { --tone: var(--problem);  background: var(--problem-bg);  border-color: var(--problem-line); }
.method-step.is-solution { --tone: var(--solution); background: var(--solution-bg); border-color: var(--solution-line); }
.method-step.is-benefit  { --tone: var(--benefit);  background: var(--benefit-bg);  border-color: var(--benefit-line); }
.method-step h3 {
    display:flex; align-items:center; gap:.6rem;
    font-family:'IBM Plex Mono', ui-monospace, monospace;
    font-size:.75rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
    color: var(--tone); margin-bottom:.75rem;
}
.method-step h3 svg { width:1.05rem; height:1.05rem; }
.method-step p { font-size:.875rem; line-height:1.75; color: var(--ink-600); }
@media (min-width:900px) {
    /* Centred on the grid gap itself, not on a hand-tuned offset: left edge is
       placed at the middle of the gap, then the arrow is pulled back by half
       its own width, so it stays centred whatever the gap or icon size is. */
    .method-step:not(:last-child)::after {
        content:""; position:absolute; z-index:2;
        top:50%;
        left: calc(100% + (var(--method-gap) / 2));
        transform: translate(-50%, -50%);
        width:1.35rem; height:1.35rem;
        background-color: var(--ink-300);
        -webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12h14'/><path d='m12 5 7 7-7 7'/></svg>") center/contain no-repeat;
        mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12h14'/><path d='m12 5 7 7-7 7'/></svg>") center/contain no-repeat;
    }
}

/* -----------------------------------------------------------------------------
   9 · WHAT YOU GET
   A comparison table, not six little cards. Three fixed columns with their
   headings stated once at the top means a reader learns the structure once and
   then only reads content; six repeated tri-colour cards made them re-learn the
   layout on every tile.
   -------------------------------------------------------------------------- */
.fitgrid { border:1px solid var(--line); border-radius: var(--r-xl); overflow:hidden; background:#fff; box-shadow: var(--sh-1); }

.fit-head { display:none; }
@media (min-width:1024px) {
    .fit-head {
        display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.15fr) minmax(0,1fr);
        background: var(--surface-alt); border-bottom:1px solid var(--line);
    }
    .fit-head > div { padding:.9rem 1.5rem; }
    .fit-head > div + div { border-left:1px solid var(--line); }
}
.fit-label {
    display:flex; align-items:center; gap:.5rem;
    font-family:'IBM Plex Mono', ui-monospace, monospace;
    font-size:.6875rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
    color: var(--tone, var(--ink-500));
}
.fit-label svg { width:.95rem; height:.95rem; }
.fit-head .is-problem  { --tone: var(--problem); }
.fit-head .is-solution { --tone: var(--solution); }
.fit-head .is-benefit  { --tone: var(--benefit); }

.fit-row { display:grid; border-top:1px solid var(--line); transition: background .2s; }
.fit-row:first-of-type { border-top:0; }
@media (min-width:1024px) {
    .fit-row { grid-template-columns:minmax(0,1fr) minmax(0,1.15fr) minmax(0,1fr); }
    .fit-row:hover { background: #fcfdff; }
}
.fit-cell { padding:1.25rem 1.5rem; --tone: var(--ink-500); }
@media (min-width:1024px) { .fit-cell + .fit-cell { border-left:1px solid var(--line); } }
@media (max-width:1023px) { .fit-cell + .fit-cell { border-top:1px dashed var(--line); } }

.fit-cell.is-problem  { --tone: var(--problem);  background: linear-gradient(90deg, var(--problem-bg), #fff 70%); }
.fit-cell.is-solution { --tone: var(--solution); }
.fit-cell.is-benefit  { --tone: var(--benefit);  background: linear-gradient(270deg, var(--benefit-bg), #fff 70%); }

/* on narrow screens each cell states which column it is; on desktop the header
   row already says it, so the repeated labels are hidden */
.fit-cell .fit-label { margin-bottom:.6rem; }
@media (min-width:1024px) { .fit-cell .fit-label { display:none; } }

.fit-cell p { font-size:.8125rem; line-height:1.7; color: var(--ink-600); }
.fit-cell.is-problem p { font-size:.9375rem; font-weight:600; line-height:1.5; color: var(--ink-900); }
.fit-cell.is-benefit p { color: var(--ink-700); font-weight:500; }
.fit-cell.is-benefit p strong { color: var(--benefit); font-weight:700; }

/* -----------------------------------------------------------------------------
   10 · CASE STUDIES - a tab strip, then one dossier at a time
   -------------------------------------------------------------------------- */
/* clip, not hidden: overflow:hidden would make this a scroll container and
   silently kill the sticky gallery inside each case. */
.cases {
    border:1px solid var(--line); border-radius: var(--r-2xl);
    overflow:clip; background:#fff; box-shadow: var(--sh-2);
}

/* The project switcher stays with the reader through a long dossier, so the
   other five projects are always one click away.

   It pins below the site's global header rather than at the viewport edge,
   so it is never covered once this page is deployed into the production
   shell. Background must stay opaque or the case body shows through it. */
.case-tabs {
    position:sticky; top: var(--site-header); z-index:5;
    display:flex; gap:.4rem; padding:.75rem;
    background: var(--surface-alt); border-bottom:1px solid var(--line);
    overflow-x:auto; scrollbar-width:none;
    transition: box-shadow .25s var(--ease);
}
.case-tabs::-webkit-scrollbar { display:none; }
.case-tabs.is-stuck { box-shadow:0 10px 22px -16px rgba(15,23,42,.55); }
.case-tab {
    flex:1 0 auto; min-width:11.5rem;
    display:flex; align-items:center; gap:.7rem;
    padding:.75rem .9rem; border-radius: var(--r-md);
    border:1px solid transparent; background:transparent; text-align:left;
    transition: background .25s, border-color .25s, box-shadow .25s;
    --proj: var(--b-600);
}
.case-tab:hover { background:#fff; border-color: var(--line); }
.case-tab.is-active { background:#fff; border-color: color-mix(in srgb, var(--proj) 40%, var(--line)); box-shadow: var(--sh-2); }
.case-tab-no {
    display:grid; place-items:center; flex-shrink:0;
    width:1.85rem; height:1.85rem; border-radius:.55rem;
    font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:.6875rem; font-weight:700;
    background: var(--surface-alt-2); color: var(--ink-500);
    transition: background .25s, color .25s;
}
.case-tab.is-active .case-tab-no { background: var(--proj); color:#fff; }
.case-tab-name { display:block; font-size:.875rem; font-weight:700; color: var(--ink-800); line-height:1.3; }
.case-tab-win { display:block; font-size:.6875rem; color: var(--ink-400); margin-top:.1rem; line-height:1.3; }
.case-tab.is-active .case-tab-win { color: var(--benefit); font-weight:600; }

.case { display:none; --proj: var(--b-600); }
.case.is-active { display:block; animation: caseIn .35s var(--ease) both; }
@keyframes caseIn { from { opacity:0; transform: translateY(8px); } to { opacity:1; transform:none; } }

/* dark dossier header */
.case-head { position:relative; overflow:hidden; padding:1.9rem 1.75rem; background: linear-gradient(135deg, var(--navy-900), #0b1240); }
@media (min-width:768px) { .case-head { padding:2.15rem 2.25rem; } }
.case-head::before {
    content:""; position:absolute; inset:0; pointer-events:none;
    background: radial-gradient(520px 240px at 88% 0%, color-mix(in srgb, var(--proj) 45%, transparent), transparent 70%);
}
.case-head::after { content:""; position:absolute; left:0; right:0; bottom:0; height:3px; background: linear-gradient(90deg, var(--proj), transparent 75%); }
.case-head-in { position:relative; z-index:1; }

.case-id { display:flex; align-items:center; gap:.85rem; flex-wrap:wrap; }
.case-name { font-size:1.35rem; font-weight:800; letter-spacing:-.02em; color:#fff; line-height:1.1; }
.case-kind {
    font-family:'IBM Plex Mono', ui-monospace, monospace;
    font-size:.65rem; font-weight:600; letter-spacing:.11em; text-transform:uppercase;
    color: rgba(203,213,225,.78);
    border:1px solid rgba(148,163,184,.3); border-radius: var(--r-pill); padding:.35rem .7rem;
}
.case-claim {
    margin-top:.95rem;
    font-size:clamp(1.1rem, .95rem + .7vw, 1.5rem);
    font-weight:700; letter-spacing:-.02em; line-height:1.35; color:#fff; max-width:56ch;
}
.case-claim mark { background:none; color:#6ee7b7; }
.case-visit {
    display:inline-flex; align-items:center; gap:.5rem; margin-top:1.1rem;
    font-size:.8125rem; font-weight:700; color:#fff;
    background: rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.2);
    padding:.6rem 1.05rem; border-radius: var(--r-pill);
    transition: background .2s, gap .2s var(--ease);
}
.case-visit:hover { background: rgba(255,255,255,.2); gap:.75rem; }
.case-visit svg { width:.9rem; height:.9rem; }

.case-chips { display:flex; flex-wrap:wrap; gap:.4rem; margin-top:1.15rem; }
.case-chips .chip {
    display:inline-flex; align-items:center; gap:.4rem;
    padding:.35rem .7rem; border-radius: var(--r-pill);
    background: rgba(255,255,255,.07); border:1px solid rgba(148,163,184,.2);
    font-size:.7rem; font-weight:600; color:#cbd5e1;
}
.case-chips .chip img { width:.85rem; height:.85rem; object-fit:contain; }
.case-chips .chip svg { width:.8rem; height:.8rem; color: var(--b-400); }

/* body: three tracks beside the screens, so the gallery is part of the case
   rather than a separate slab bolted underneath it */
.case-body { display:grid; }
@media (min-width:1180px) { .case-body { grid-template-columns: minmax(0,1.15fr) minmax(0,1fr); } }

/* A case with no published screenshots gets the full width for its three
   tracks instead of a half-empty column beside them. */
.case-body.is-solo { grid-template-columns: minmax(0,1fr); }
@media (min-width:900px) { .case-body.is-solo .psb { grid-template-columns:repeat(3, minmax(0,1fr)); } }
@media (min-width:900px) {
    .case-body.is-solo .track { border-bottom:0; border-right:1px solid var(--line); }
    .case-body.is-solo .track:last-child { border-right:0; }
}

.psb { display:grid; }
@media (min-width:720px) and (max-width:1179px) { .psb { grid-template-columns:repeat(3, minmax(0,1fr)); } }

.track { position:relative; padding:1.5rem 1.5rem; border-bottom:1px solid var(--line); --tone: var(--ink-500); }
@media (min-width:720px) and (max-width:1179px) {
    .track { border-bottom:0; border-right:1px solid var(--line); }
    .track:last-child { border-right:0; }
}
@media (min-width:1180px) { .track { padding:1.6rem 1.85rem; } .track:last-child { border-bottom:0; } }
.track.is-problem  { --tone: var(--problem);  background: linear-gradient(180deg, var(--problem-bg), #fff 70%); }
.track.is-solution { --tone: var(--solution); background: linear-gradient(180deg, var(--solution-bg), #fff 70%); }
.track.is-benefit  { --tone: var(--benefit);  background: linear-gradient(180deg, var(--benefit-bg), #fff 70%); }

.track-head { display:flex; align-items:center; gap:.65rem; margin-bottom:.95rem; }
.track-ico {
    display:grid; place-items:center; width:2.1rem; height:2.1rem; border-radius:.6rem;
    background: color-mix(in srgb, var(--tone) 12%, #fff);
    border:1px solid color-mix(in srgb, var(--tone) 30%, #fff);
}
.track-ico svg { width:1.05rem; height:1.05rem; color: var(--tone); stroke-width:2; }
.track-head h4 {
    font-family:'IBM Plex Mono', ui-monospace, monospace;
    font-size:.72rem; font-weight:700; letter-spacing:.13em; text-transform:uppercase; color: var(--tone);
}
.track-lead { font-size:.9375rem; font-weight:600; line-height:1.6; color: var(--ink-900); margin-bottom:.85rem; }

.track-list { list-style:none; margin:0; padding:0; display:grid; gap:.6rem; }
.track-list li { position:relative; padding-left:1.45rem; font-size:.8125rem; line-height:1.7; color: var(--ink-600); }
.track-list li::before {
    content:""; position:absolute; left:0; top:.42rem; width:.55rem; height:.55rem;
    border-radius:2px; background: color-mix(in srgb, var(--tone) 45%, #fff); border:1px solid var(--tone);
}
.track.is-benefit .track-list li::before { border-radius:99px; background: var(--tone); border-color: var(--tone); }

.gains { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:.6rem; margin-top:1.1rem; }
.gain { background:#fff; border:1px solid var(--benefit-line); border-radius: var(--r-md); padding:.85rem .9rem; }
.gain b {
    display:block; font-family:'IBM Plex Mono', ui-monospace, monospace;
    font-size:1.3rem; font-weight:700; color: var(--benefit); letter-spacing:-.02em; line-height:1;
}
.gain span { display:block; margin-top:.35rem; font-size:.7rem; line-height:1.45; color: var(--ink-500); }

/* -----------------------------------------------------------------------------
   11 · CASE GALLERY - same surface as the case, fixed stage, no layout shift
   -------------------------------------------------------------------------- */
.gal { padding:1.5rem; background:#fff; border-top:1px solid var(--line); }
@media (min-width:1180px) {
    .gal { border-top:0; border-left:1px solid var(--line); padding:1.6rem 1.75rem; }
    /* The three tracks are taller than the gallery, which left a dead white
       block under the thumbnails. Sticking the gallery to the top of its
       column turns that space into something useful: the screens stay in
       view while the problem and solution are being read.

       It has to clear the pinned tab strip above it, so the offset is the
       measured strip height (set as --tabs-h by the script) plus a gutter. */
    .gal-inner { position:sticky; top: calc(var(--site-header) + var(--tabs-h, 4.75rem) + 1.25rem); }
}

/* full-width note for a case with no published screens */
.gal.is-note { border-top:1px solid var(--line); border-left:0; padding:1.25rem 1.75rem; background: var(--surface-alt); }

.frame { border-radius: var(--r-lg); overflow:hidden; border:1px solid var(--line); background:#fff; box-shadow: var(--sh-2); }
.frame-bar { display:flex; align-items:center; gap:.4rem; padding:.55rem .8rem; background: var(--surface-alt-2); border-bottom:1px solid var(--line); }
.frame-dot { width:.5rem; height:.5rem; border-radius:99px; }
.frame-url {
    margin-left:.55rem; flex:1;
    font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:.65rem; color: var(--ink-500);
    background:#fff; border:1px solid var(--line); border-radius: var(--r-pill); padding:.22rem .7rem;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* The stage keeps a fixed aspect ratio and crops to the top of the screenshot.
   Screenshots of full pages vary wildly in height; letting them size the box
   made the whole page jump every time someone stepped through the gallery. */
.stage {
    position:relative; display:block; width:100%;
    aspect-ratio: 16 / 10;
    background: var(--surface-alt-2);
    cursor:zoom-in; overflow:hidden;
}
.stage img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:top center; }
.stage::after {
    content:""; position:absolute; inset:0; opacity:0; transition:opacity .3s;
    background: linear-gradient(180deg, transparent 55%, rgba(15,23,42,.42));
}
.stage:hover::after { opacity:1; }
.stage-zoom {
    position:absolute; right:.8rem; bottom:.8rem; z-index:2;
    display:inline-flex; align-items:center; gap:.4rem;
    padding:.45rem .8rem; border-radius: var(--r-pill);
    background: rgba(15,23,42,.88); color:#fff; font-size:.6875rem; font-weight:600;
    opacity:0; transform:translateY(6px); pointer-events:none;
    transition: opacity .3s var(--ease), transform .3s var(--ease);
}
.stage-zoom svg { width:.85rem; height:.85rem; }
.stage:hover .stage-zoom, .stage:focus-visible .stage-zoom { opacity:1; transform:none; }

.gal-bar { display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-top:.9rem; }
.gal-cap { display:flex; align-items:center; gap:.55rem; min-width:0; }
.gal-cap svg { width:1rem; height:1rem; color: var(--ink-400); flex-shrink:0; }
.gal-cap span { font-size:.8125rem; font-weight:600; color: var(--ink-700); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.gal-count { font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:.6875rem; color: var(--ink-400); }
.gal-arrows { display:flex; gap:.4rem; }
.gal-arrow {
    display:grid; place-items:center; width:2.1rem; height:2.1rem;
    border-radius: var(--r-sm); border:1px solid var(--line); background:#fff; color: var(--ink-600);
    transition: background .2s, border-color .2s, color .2s;
}
.gal-arrow:hover { background: var(--b-600); border-color: var(--b-600); color:#fff; }
.gal-arrow svg { width:1.05rem; height:1.05rem; }

.thumbs { display:flex; gap:.45rem; margin-top:.85rem; overflow-x:auto; padding-bottom:.4rem; scroll-snap-type:x proximity; }
.thumbs::-webkit-scrollbar { height:5px; }
.thumb {
    position:relative; flex:0 0 auto; width:5.4rem; height:3.4rem;
    border-radius:.5rem; overflow:hidden; border:1px solid var(--line); background:#fff;
    scroll-snap-align:start; opacity:.6;
    transition: opacity .25s, border-color .25s, transform .25s var(--ease), box-shadow .25s;
}
.thumb img { width:100%; height:100%; object-fit:cover; object-position:top center; display:block; }
.thumb:hover { opacity:1; transform:translateY(-2px); box-shadow: var(--sh-2); }
.thumb.is-active { opacity:1; border-color: var(--proj); box-shadow:0 0 0 2px color-mix(in srgb, var(--proj) 30%, #fff); }

.gal-empty {
    display:flex; align-items:flex-start; gap:.75rem;
    padding:1.1rem 1.15rem; border:1px dashed var(--line); border-radius: var(--r-md);
    background: var(--surface-alt); font-size:.8125rem; line-height:1.7; color: var(--ink-500);
}
.gal-empty svg { width:1.05rem; height:1.05rem; color: var(--ink-400); flex-shrink:0; margin-top:.15rem; }

/* -----------------------------------------------------------------------------
   12 · RESULTS BAND
   -------------------------------------------------------------------------- */
.band {
    position:relative; overflow:hidden;
    background:
        radial-gradient(760px 400px at 82% 6%, rgba(37,99,235,.24), transparent 62%),
        linear-gradient(160deg, var(--navy-900), #0a0f30);
}
.band::before {
    content:""; position:absolute; inset:0; pointer-events:none;
    background-image:
        linear-gradient(rgba(148,163,184,.05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(148,163,184,.05) 1px, transparent 1px);
    background-size:56px 56px;
    mask-image: radial-gradient(circle at 50% 0%, #000, transparent 74%);
    -webkit-mask-image: radial-gradient(circle at 50% 0%, #000, transparent 74%);
}
.band-in { position:relative; z-index:1; }

.wins { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:.75rem; }
@media (min-width:900px) { .wins { grid-template-columns:repeat(4, minmax(0,1fr)); } }
.win {
    /* opaque, not translucent: the blueprint grid behind this section would
       otherwise draw a line straight through a numeral and read as a strikethrough */
    background:#0a0f2e;
    border:1px solid rgba(148,163,184,.18);
    border-radius: var(--r-lg);
    padding:1.15rem 1.1rem; position:relative; overflow:hidden;
}
.win::after { content:""; position:absolute; left:0; top:0; bottom:0; width:3px; background: linear-gradient(180deg, var(--b-400), rgba(96,165,250,0)); }
.win.is-green::after { background: linear-gradient(180deg, #34d399, rgba(52,211,153,0)); }
.win b { display:block; font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:1.7rem; font-weight:700; color:#fff; letter-spacing:-.03em; line-height:1; }
.win.is-green b { color:#6ee7b7; }
.win span { display:block; margin-top:.45rem; font-size:.75rem; line-height:1.5; color: rgba(148,163,184,.95); }

/* -----------------------------------------------------------------------------
   13 · CAPABILITY TILES
   -------------------------------------------------------------------------- */
.cap {
    display:flex; gap:.95rem; align-items:flex-start;
    background:#fff; border:1px solid var(--line); border-radius: var(--r-lg);
    padding:1.2rem 1.25rem; height:100%; --tone: var(--b-600);
    transition: border-color .25s, box-shadow .25s, transform .25s var(--ease);
}
.cap:hover { border-color: color-mix(in srgb, var(--tone) 42%, var(--line)); box-shadow: var(--sh-2); transform: translateY(-3px); }
.cap-ico {
    display:grid; place-items:center; flex-shrink:0; width:2.6rem; height:2.6rem; border-radius:.7rem;
    background: color-mix(in srgb, var(--tone) 9%, #fff); border:1px solid color-mix(in srgb, var(--tone) 22%, #fff);
}
.cap-ico svg { width:1.25rem; height:1.25rem; color: var(--tone); stroke-width:1.85; }
.cap h3 { font-size:.9375rem; font-weight:600; color: var(--ink-900); margin-bottom:.35rem; }
.cap p { font-size:.8125rem; line-height:1.7; color: var(--ink-500); }

/* -----------------------------------------------------------------------------
   14 · STACK ROWS
   -------------------------------------------------------------------------- */
.stack-row { display:grid; gap:1rem; padding:1.4rem 0; border-top:1px solid var(--line); }
@media (min-width:900px) { .stack-row { grid-template-columns:14rem minmax(0,1fr); gap:2rem; align-items:start; } }
.stack-row:last-child { border-bottom:1px solid var(--line); }
.stack-label { font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:.7rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color: var(--ink-900); }
.stack-note { margin-top:.4rem; font-size:.8125rem; line-height:1.65; color: var(--ink-500); }
.stack-items { display:flex; flex-wrap:wrap; gap:.5rem; }
.tech {
    display:inline-flex; align-items:center; gap:.5rem;
    padding:.55rem .95rem; border-radius: var(--r-pill);
    background: var(--surface-alt); border:1px solid var(--line);
    font-size:.8125rem; font-weight:600; color: var(--ink-700);
    transition: border-color .2s, background .2s, transform .2s var(--ease);
}
.tech:hover { border-color: var(--b-200); background:#fff; transform: translateY(-2px); }
.tech img { width:1.05rem; height:1.05rem; object-fit:contain; }
.tech svg { width:.95rem; height:.95rem; color: var(--b-600); }

/* -----------------------------------------------------------------------------
   15 · PROCESS
   -------------------------------------------------------------------------- */
.steps { display:grid; gap:1.25rem; counter-reset: step; }
@media (min-width:768px) { .steps { grid-template-columns:repeat(2, minmax(0,1fr)); gap:1rem 2rem; } }
@media (min-width:1200px) { .steps { grid-template-columns:repeat(3, minmax(0,1fr)); } }
.step { position:relative; padding-left:3.5rem; padding-bottom:.25rem; }
.step::before {
    counter-increment: step; content: "0" counter(step);
    position:absolute; left:0; top:-.15rem;
    display:grid; place-items:center; width:2.5rem; height:2.5rem; border-radius:99px;
    background: var(--b-50); border:1px solid var(--b-200); color: var(--b-700);
    font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:.8125rem; font-weight:700;
    transition: background .3s, color .3s, border-color .3s;
}
.step:hover::before { background: var(--b-600); border-color: var(--b-600); color:#fff; }
.step h3 { font-size:1rem; font-weight:600; color: var(--ink-900); margin-bottom:.4rem; }
.step p { font-size:.8125rem; line-height:1.7; color: var(--ink-500); }
.step-out {
    display:inline-flex; align-items:center; gap:.4rem; margin-top:.75rem;
    font-family:'IBM Plex Mono', ui-monospace, monospace;
    font-size:.625rem; font-weight:600; letter-spacing:.07em; text-transform:uppercase;
    color: var(--benefit); background: var(--benefit-bg); border:1px solid var(--benefit-line);
    padding:.3rem .65rem; border-radius: var(--r-pill);
}
.step-out svg { width:.8rem; height:.8rem; }

/* -----------------------------------------------------------------------------
   16 · ENGAGEMENT
   -------------------------------------------------------------------------- */
.eng {
    position:relative; display:flex; flex-direction:column; height:100%;
    background:#fff; border:1px solid var(--line); border-radius: var(--r-xl); overflow:hidden;
    transition: border-color .3s, box-shadow .3s, transform .3s var(--ease);
}
.eng:hover { border-color: var(--b-200); box-shadow: var(--sh-3); transform: translateY(-4px); }
.eng.is-featured { border-color: var(--b-300); box-shadow: var(--sh-3); }
.eng-flag {
    position:absolute; top:1rem; right:1rem;
    font-family:'IBM Plex Mono', ui-monospace, monospace;
    font-size:.6rem; font-weight:700; letter-spacing:.09em; text-transform:uppercase;
    background: var(--b-600); color:#fff; padding:.3rem .6rem; border-radius: var(--r-pill);
}
.eng-head { display:flex; align-items:center; gap:.7rem; padding:1.15rem 1.5rem; background: var(--surface-alt); border-bottom:1px solid var(--line); }
.eng.is-featured .eng-head { background: linear-gradient(135deg, var(--b-50), #eef2ff); border-bottom-color: var(--b-100); }
.eng-head svg { width:1.15rem; height:1.15rem; color: var(--b-600); }
.eng-head span { font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:.65rem; font-weight:600; letter-spacing:.09em; text-transform:uppercase; color: var(--ink-500); }
.eng-body { display:flex; flex-direction:column; flex:1; padding:1.6rem 1.5rem; }
.eng-body h3 { font-size:1.15rem; font-weight:600; color: var(--ink-900); margin-bottom:.55rem; }
.eng-body > p { font-size:.8125rem; line-height:1.7; color: var(--ink-500); margin-bottom:1.15rem; }
.eng-list { list-style:none; margin:0 0 1.25rem; padding:0; display:grid; gap:.6rem; }
.eng-list li { position:relative; padding-left:1.5rem; font-size:.8125rem; line-height:1.6; color: var(--ink-600); }
.eng-list li::before {
    content:""; position:absolute; left:0; top:.25rem; width:1rem; height:1rem;
    background-color: var(--benefit);
    -webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") center/contain no-repeat;
    mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") center/contain no-repeat;
}
.eng-best { margin-top:auto; padding-top:1.1rem; border-top:1px dashed var(--line); font-size:.75rem; line-height:1.65; color: var(--ink-500); }
.eng-best strong { color: var(--ink-800); }

/* -----------------------------------------------------------------------------
   17 · FAQ - one full-width column so a question fits on a single line
   -------------------------------------------------------------------------- */
.faq { display:grid; gap:.6rem; counter-reset: faq; }
.faq-item { background:#fff; border:1px solid var(--line); border-radius: var(--r-md); overflow:hidden; transition: border-color .25s, box-shadow .25s; }
.faq-item:hover { border-color: var(--b-200); }
.faq-item.is-open { border-color: var(--b-200); box-shadow: var(--sh-2); }
.faq-q {
    display:flex; align-items:center; gap:.9rem; width:100%;
    padding:1rem 1.25rem; text-align:left; transition: background .2s;
}
.faq-q:hover { background: var(--surface-alt); }

/* Numbered index, generated rather than hand-typed: the numbering stays
   correct if a question is ever added, removed or reordered.
   A fixed width keeps every question text starting on the same vertical line. */
.faq-q::before {
    counter-increment: faq;
    content: counter(faq, decimal-leading-zero);
    flex-shrink:0; width:1.5rem;
    font-family:'IBM Plex Mono', ui-monospace, monospace;
    font-size:.75rem; font-weight:600; letter-spacing:.02em;
    color: var(--ink-400);
    transition: color .2s;
}
.faq-item.is-open .faq-q::before { color: var(--b-600); }
.faq-q:hover::before { color: var(--ink-600); }
.faq-q > span {
    flex:1; min-width:0;
    font-size:.9375rem; font-weight:600; color: var(--ink-800); line-height:1.4;
}
@media (min-width:900px) {
    /* the questions are short enough to sit on one line at this width, and a
       one-line question scans far faster than a wrapped one */
    .faq-q > span { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
}
.faq-chev { flex-shrink:0; width:1.15rem; height:1.15rem; color: var(--ink-400); transition: transform .3s var(--ease), color .2s; }
.faq-item.is-open .faq-chev { transform: rotate(180deg); color: var(--b-600); }
.faq-a { display:grid; grid-template-rows:0fr; transition: grid-template-rows .35s var(--ease); }
.faq-item.is-open .faq-a { grid-template-rows:1fr; }
.faq-a > div { overflow:hidden; }
/* left padding = question padding (1.25) + number column (1.5) + gap (0.9),
   so the answer starts on the same line as the question text above it */
.faq-a p { padding:0 3rem 1.15rem 3.65rem; font-size:.875rem; line-height:1.8; color: var(--ink-500); }
@media (max-width:640px) { .faq-a p { padding-left:1.25rem; padding-right:1.25rem; } }

/* -----------------------------------------------------------------------------
   18 · CLOSING CTA
   -------------------------------------------------------------------------- */
.cta-dark {
    position:relative; overflow:hidden; border-radius: var(--r-2xl);
    background:
        radial-gradient(680px 380px at 12% 18%, rgba(37,99,235,.32), transparent 62%),
        linear-gradient(135deg, var(--navy-900), #0b1240);
}
.cta-dark::before {
    content:""; position:absolute; inset:0; pointer-events:none;
    background-image:
        linear-gradient(rgba(148,163,184,.06) 1px, transparent 1px),
        linear-gradient(90deg, rgba(148,163,184,.06) 1px, transparent 1px);
    background-size:48px 48px;
    mask-image: radial-gradient(circle at 82% 55%, #000, transparent 72%);
    -webkit-mask-image: radial-gradient(circle at 82% 55%, #000, transparent 72%);
}
.cta-opt {
    display:block; height:100%;
    background: rgba(255,255,255,.05); border:1px solid rgba(148,163,184,.2);
    border-radius: var(--r-xl); padding:1.5rem;
    transition: background .25s, border-color .25s, transform .25s var(--ease);
}
.cta-opt:hover { background: rgba(255,255,255,.1); border-color: rgba(96,165,250,.45); transform: translateY(-3px); }
.cta-opt .ico { display:grid; place-items:center; width:2.6rem; height:2.6rem; border-radius:.75rem; background: rgba(59,130,246,.16); border:1px solid rgba(96,165,250,.28); margin-bottom:1rem; flex-shrink:0; }
.cta-opt .ico svg { width:1.25rem; height:1.25rem; color: var(--b-300); }
.cta-opt h3 { font-size:1rem; font-weight:700; color:#fff; margin-bottom:.35rem; }
.cta-opt p { font-size:.8125rem; line-height:1.65; color: rgba(148,163,184,.95); }

/* compact row variant - used when the CTA cards sit below the copy instead
   of filling a whole column, so icon + text sit side by side at a smaller size */
.cta-opt-sm {
    display:flex; align-items:center; gap:.85rem;
    padding:1rem 1.1rem; height:auto;
}
.cta-opt-sm .ico { width:2.15rem; height:2.15rem; margin-bottom:0; }
.cta-opt-sm .ico svg { width:1.05rem; height:1.05rem; }
.cta-opt-sm h3 { font-size:.9375rem; margin-bottom:.15rem; }
.cta-opt-sm p { font-size:.75rem; }
.cta-note { display:inline-flex; align-items:center; gap:.5rem; font-size:.75rem; color: rgba(148,163,184,.95); }
.cta-note svg { width:.9rem; height:.9rem; color:#34d399; }

/* -----------------------------------------------------------------------------
   19 · LIGHTBOX
   -------------------------------------------------------------------------- */
.lb { position:fixed; inset:0; z-index:90; display:none; align-items:center; justify-content:center; padding:1rem; background: rgba(7,10,36,.9); backdrop-filter: blur(6px); }
.lb.is-open { display:flex; animation: lbIn .2s ease-out; }
@keyframes lbIn { from { opacity:0; } to { opacity:1; } }
.lb-shell { position:relative; width:100%; max-width:66rem; background:#fff; border-radius: var(--r-xl); overflow:hidden; box-shadow:0 40px 90px -30px rgba(0,0,0,.85); max-height:92vh; display:flex; flex-direction:column; }
.lb-img { width:100%; height:auto; max-height:72vh; object-fit:contain; background: var(--surface-alt-2); display:block; }
.lb-foot { display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:1rem 1.25rem; border-top:1px solid var(--line); }
.lb-meta { font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:.65rem; font-weight:600; letter-spacing:.09em; text-transform:uppercase; color: var(--b-600); }
.lb-cap { font-size:1rem; font-weight:700; color: var(--ink-900); margin-top:.2rem; }
.lb-count { font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:.75rem; color: var(--ink-400); flex-shrink:0; }
.lb-btn { position:absolute; z-index:2; display:grid; place-items:center; width:2.5rem; height:2.5rem; border-radius:99px; background: rgba(255,255,255,.94); color: var(--ink-800); box-shadow:0 6px 18px -6px rgba(15,23,42,.5); transition: background .2s, transform .2s; }
.lb-btn:hover { background:#fff; transform: scale(1.06); }
.lb-btn svg { width:1.25rem; height:1.25rem; }
.lb-close { top:.9rem; right:.9rem; }
.lb-prev { top:calc(50% - 4rem); left:.9rem; }
.lb-next { top:calc(50% - 4rem); right:.9rem; }

/* -----------------------------------------------------------------------------
   20 · BACK TO TOP + REVEAL
   -------------------------------------------------------------------------- */
.to-top {
    position:fixed; right:1.25rem; bottom:1.25rem; z-index:55;
    display:grid; place-items:center; width:2.9rem; height:2.9rem; border-radius:99px;
    background: var(--b-600); color:#fff; box-shadow: var(--sh-blue);
    opacity:0; visibility:hidden; transform: translateY(12px);
    transition: opacity .3s var(--ease), transform .3s var(--ease), visibility .3s, background .2s;
}
.to-top.is-shown { opacity:1; visibility:visible; transform:none; }
.to-top:hover { background: var(--b-700); }
.to-top svg { width:1.2rem; height:1.2rem; }

.reveal { opacity:0; transform: translateY(20px); transition: opacity .65s var(--ease), transform .65s var(--ease); transition-delay: var(--d, 0s); }
.reveal.is-in { opacity:1; transform:none; }

/* Fade with no transform. Used on any element that is the containing block for
   a sticky child: while a translate is animating, the transformed ancestor
   drags its sticky descendants with it, so the pinned tab strip and gallery
   would sit ~20px low until the reveal finished. */
.reveal.is-fade-only, .reveal.is-fade-only.is-in { transform: none; }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior:auto; }
    .reveal { opacity:1; transform:none; transition:none; }
    *, *::before, *::after { animation-duration:.01ms !important; transition-duration:.01ms !important; }
}

/* -----------------------------------------------------------------------------
   19 · MOBILE OVERRIDES  (phones only - nothing here reaches the desktop layout)
   Everything below is scoped to max-width, so every rule above that is written
   as min-width is untouched. Kept at the end of the file so it is the last word
   in the cascade for the small screens it targets.
   -------------------------------------------------------------------------- */
@media (max-width:767px) {

    /* --- CTA STRIP: 75% width + generous padding is tuned for desktop; on a
       phone that leaves too little room for the heading/paragraph to breathe,
       so it goes full width with tighter padding. */
    .cta-strip { width:100%; padding:1.75rem 1.5rem; }

    /* --- HERO: no banner on a phone ---------------------------------------
       The banner is framed with background-size:contain and pinned center
       right, which on a narrow screen puts the diagram directly behind the
       headline and the paragraph. Dropping the layer leaves the navy gradient
       already declared on .hero, so the copy sits on a clean field.
       The veil was shaped to darken the left over that image; with the image
       gone its 105deg falloff would light up the right edge for no reason,
       so it is flattened to an even top-to-bottom wash. */
    .hero-media { display:none; }
    .hero-glow { display:none; }
    .hero-veil {
        background: linear-gradient(180deg,
            rgba(7,14,30,.55) 0%,
            rgba(7,14,30,.35) 45%,
            rgba(7,14,30,.60) 100%);
    }

    /* --- CASE STUDIES: the project switcher -------------------------------
       On desktop the six projects are a single scrolling row. At phone width
       that row shows two tabs and hides the other four behind a horizontal
       swipe with no affordance. Two per row stacks all six in view instead. */
    .case-tabs {
        display:grid; grid-template-columns:repeat(2, minmax(0,1fr));
        gap:.5rem; overflow-x:visible;
        /* A three-row switcher pinned under the site header would take most of
           a phone screen, so it scrolls away with the rest of the page. */
        position:static;
    }
    /* The script still toggles .is-stuck from a rect test; the strip no longer
       pins, so the shadow that went with pinning would be meaningless. */
    .case-tabs.is-stuck { box-shadow:none; }
    .case-tab { flex:initial; min-width:0; padding:.7rem .75rem; gap:.55rem; }
    .case-tab-name,
    .case-tab-win { overflow-wrap:anywhere; }

    /* --- CASE STUDIES: the overflow ---------------------------------------
       .cases clips its overflow, so anything inside that cannot shrink below
       the phone's width gets its right edge cut off - which is what was
       trimming the problem and solution copy mid-sentence.

       The element forcing that width is .frame-url: a flex child with
       white-space:nowrap, so its automatic minimum size is the full unwrapped
       URL (the longest is 37 characters). That floor propagates up through
       .gal to the case-body grid track. min-width:0 lets it shrink and hands
       the job to the ellipsis it already declares. The rest are the same
       release valve applied to every grid item on the way up, so no future
       wide child can push the case out of the viewport again. */
    .frame-url { min-width:0; }
    .cases, .case-head, .case-body, .psb, .track, .gal, .gal-inner { min-width:0; }
    .case-body > *, .psb > * { min-width:0; }
    .track-lead, .track-list li, .case-claim, .case-kind { overflow-wrap:anywhere; }

    /* Breathing room back: the desktop gutters are generous for a 360px screen
       once the content is actually wrapping inside them. */
    .track { padding:1.25rem 1.15rem; }
    .gal { padding:1.15rem; }
    .case-head { padding:1.5rem 1.15rem; }

    /* Two stat cards side by side leaves ~90px each after padding. */
    .gains { grid-template-columns:minmax(0,1fr); }
}
