@charset "UTF-8";
/* Citelx — home.
 *
 * Loaded on the front page only, after main.css, so the rest of the site is
 * untouched while this page is rebuilt.
 *
 * WHAT CHANGED, AND WHY
 *
 * The previous home page had more motion than message. Six effects competed for
 * attention at once — three drifting aurora blobs, a sweeping shine on every
 * primary button, a pinging dot on every eyebrow, a shimmering skeleton, two
 * counter-rotating orbit rings and a scrolling grid floor — so nothing was
 * emphasised, because everything was. Restraint is the single biggest
 * difference between a page that looks expensive and one that looks busy.
 *
 * The rules here:
 *
 *   1. ONE moment of motion per screen, and it must mean something. Bars fill
 *      because they are showing coverage. The answer types because that is what
 *      an answer engine does. Nothing moves purely to prove it can.
 *   2. The rotating orbit is gone. Text that rotates cannot be read and a link
 *      that moves cannot be clicked — it was the worst UX on the page while
 *      being the most technically impressive part of it. The same nine surfaces
 *      are now a still grid: scannable, clickable, and legible in a screenshot.
 *   3. Depth comes from shadow, scale and spacing — not from perspective tricks.
 *   4. Space is the layout. Section rhythm is one scale, applied consistently.
 */

/* ═══════════════ tokens ═══════════════ */

.home-v4{
  /* A warmer, deeper ink than the shared one. Pure-grey text on pure white is
     the default nobody chose; a touch of blue in the black reads intentional. */
  --ink:#0A0C12;
  --ink-2:#4A5260;
  --ink-3:#79808F;
  --ink-4:#A5ABB8;

  --paper:#FFFFFF;
  --paper-2:#F7F8FC;
  --paper-3:#EFF1F7;

  --night:#08070F;
  --night-2:#12101F;
  --night-3:#1C1930;

  --violet:#6C5CE7;
  --violet-2:#8B7CFF;
  --violet-3:#B8A9FF;
  --cyan:#22C1DC;
  --mint:#3ADFA5;

  --line:rgba(10,12,18,.09);
  --line-2:rgba(10,12,18,.055);
  --line-d:rgba(255,255,255,.10);
  --line-d2:rgba(255,255,255,.06);

  /* Shadows in the brand hue rather than neutral grey — the difference is
     subtle and it is most of why a card looks "designed". */
  --sh-1:0 1px 2px rgba(10,12,18,.04), 0 2px 8px rgba(10,12,18,.04);
  --sh-2:0 2px 4px rgba(10,12,18,.03), 0 12px 32px rgba(10,12,18,.07);
  --sh-3:0 4px 8px rgba(10,12,18,.04), 0 24px 64px rgba(10,12,18,.10);
  --sh-4:0 40px 90px rgba(10,12,18,.16), 0 8px 24px rgba(10,12,18,.06);

  --r-sm:10px;
  --r:14px;
  --r-lg:20px;
  --r-xl:28px;

  /* One spacing scale, used everywhere. */
  --s-1:8px;   --s-2:12px;  --s-3:16px;  --s-4:24px;
  --s-5:32px;  --s-6:48px;  --s-7:64px;  --s-8:96px;
  --sec-y:clamp(72px,10vw,140px);

  /* Height of the site header, which sits in flow above the hero. The hero
     subtracts it to fill exactly one screen. Re-measure if the header changes. */
  --hdr:75px;

  --ease:cubic-bezier(.22,.75,.28,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
}

/* ═══════════════ type ═══════════════ */

.home-v4 h1,.home-v4 h2,.home-v4 h3,.home-v4 h4{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-weight:600;
  letter-spacing:-.035em;
  line-height:1.04;
  color:var(--ink);
  text-wrap:balance;
}
.home-v4 h1{font-size:clamp(38px,min(6.4vw,8.2vh),72px);letter-spacing:-.045em}
.home-v4 h2{font-size:clamp(30px,4.4vw,52px);line-height:1.06;letter-spacing:-.04em}
.home-v4 h3{font-size:clamp(19px,1.6vw,22px);line-height:1.25;letter-spacing:-.022em;font-weight:600}
.home-v4 h4{font-size:16px;line-height:1.35;letter-spacing:-.015em;font-weight:600}

/* The one serif on the site. A single italic phrase inside the H1 does more for
   personality than any amount of gradient, and it costs one 400-weight file. */
.home-v4 .serif{
  font-family:'Instrument Serif',Georgia,serif;
  font-style:italic;font-weight:400;
  letter-spacing:-.02em;
  padding-right:.06em;
}

.home-v4 p{color:var(--ink-2)}
.home-v4 .lead{
  font-size:clamp(17px,1.5vw,20px);line-height:1.6;color:var(--ink-2);
  letter-spacing:-.011em;text-wrap:pretty;
}
.home-v4 .mono{font-family:'IBM Plex Mono',ui-monospace,monospace}

/* Label — replaces the pill "eyebrow", which had a pinging dot and appeared on
   every section, so six of them competed at once.
   Grey 11px at .45 opacity was too far the other way — it read as a caption
   rather than the signpost that tells you which part of the argument you are
   in. Brand colour does more for prominence than size ever could, so this gains
   one point of size and one step of weight, and takes the accent. Still no
   pill and no animated dot: the point was to stop six of these shouting at
   once, not to make them invisible. */
.home-v4 .label{
  display:flex;align-items:center;gap:11px;
  font-family:'IBM Plex Mono',monospace;
  font-size:12px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--violet);margin-bottom:var(--s-4);
}
.home-v4 .label::before{
  content:'';width:26px;height:2px;border-radius:2px;background:currentColor;flex:none;
}
.home-v4 .center .label{justify-content:center}
.home-v4 .on-night .label,.home-v4 .h-night .label{color:var(--violet-3)}

/* A label carrying three claims instead of one word. The rule that prefixes
   every other label is dropped here: it exists to point at a single short
   signpost, and in front of a three-part line it reads as a fourth item that
   happens to have no text.

   The separator is a DRAWN circle, matching the dot on the hero's availability
   line, not a typographic middot. Two reasons. It is the mark this page already
   uses to separate small claims, so the two read as the same device. And a
   drawn dot is pure geometry: nothing to encode, and nothing for a stylesheet
   escape or a server charset to corrupt, which is exactly how the previous
   version broke. 5px against the hero's 7px because it sits between words here
   rather than leading a line, with the same soft halo. */
.home-v4 .label-dots::before{display:none}
.home-v4 .label-dots{
  flex-wrap:wrap;justify-content:center;gap:0 0;row-gap:6px;
}
.home-v4 .label-dots span{display:inline-flex;align-items:center;white-space:nowrap}
.home-v4 .label-dots span + span::before{
  content:'';
  width:5px;height:5px;border-radius:50%;
  background:currentColor;opacity:.55;
  box-shadow:0 0 0 2.5px rgba(184,169,255,.14);
  margin:0 13px;flex:none;
}

/* ═══════════════ layout ═══════════════ */

.home-v4 .h-sec{padding:var(--sec-y) 0;position:relative}
.home-v4 .h-sec.tight{padding:clamp(48px,6vw,80px) 0}
.home-v4 .h-alt{background:var(--paper-2)}
.home-v4 .h-night{background:var(--night);color:#F4F3F8;overflow:hidden}
.home-v4 .h-night h2,.home-v4 .h-night h3,.home-v4 .h-night h4{color:#fff}
.home-v4 .h-night p{color:#9BA2B4}

.home-v4 .h-head{max-width:660px;margin-bottom:clamp(40px,5vw,64px)}
.home-v4 .h-head.center{text-align:center;margin-inline:auto}
.home-v4 .h-head h2 + .lead{margin-top:var(--s-3)}

/* A hairline that stops short of the gutters — a full-bleed rule reads like a
   browser default, an inset one reads like a decision. */
.home-v4 .h-rule{height:1px;background:var(--line-2);margin-inline:var(--gut)}

/* ═══════════════ buttons ═══════════════ */

.home-v4 .h-btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font-size:15px;font-weight:550;line-height:1;letter-spacing:-.011em;
  padding:15px 24px;border-radius:99px;border:1px solid transparent;
  cursor:pointer;white-space:nowrap;
  transition:background .18s var(--ease),color .18s var(--ease),
             border-color .18s var(--ease),box-shadow .22s var(--ease),
             transform .22s var(--ease);
}
.home-v4 .h-btn svg{flex:none;transition:transform .26s var(--ease-out)}
.home-v4 .h-btn:hover svg{transform:translateX(3px)}

/* Solid ink, not a gradient. The gradient is now reserved for the two places
   that genuinely are the product's identity — it means more used twice. */
.home-v4 .h-btn-primary{background:var(--ink);color:#fff;box-shadow:var(--sh-2)}
.home-v4 .h-btn-primary:hover{background:#000;box-shadow:var(--sh-3);transform:translateY(-1px)}
.home-v4 .h-btn-ghost{background:transparent;color:var(--ink);border-color:var(--line)}
.home-v4 .h-btn-ghost:hover{border-color:var(--ink);background:var(--ink);color:#fff}
.home-v4 .h-night .h-btn-primary{background:#fff;color:var(--ink)}
.home-v4 .h-night .h-btn-primary:hover{background:#fff;transform:translateY(-1px)}
.home-v4 .h-night .h-btn-ghost{color:#fff;border-color:var(--line-d)}
.home-v4 .h-night .h-btn-ghost:hover{background:#fff;color:var(--ink);border-color:#fff}
.home-v4 .h-btns{display:flex;gap:10px;flex-wrap:wrap}

/* The hero pair, sized for the hero. 15px type in 15/24 padding is a fine
   in-page button and an underweight primary call to action on the largest
   block of the site; these sit under a 76px headline and have to hold their
   own against it.

   The ghost button's border was var(--line), which is ink at 9% and reads as a
   hint rather than a control: next to a solid black button it looked disabled.
   It is not the secondary action being de-emphasised, it is the second thing a
   visitor might want, so it gets a real edge. */
.home-v4 .h-hero .h-btn{font-size:15.5px;padding:16px 27px}
.home-v4 .h-hero .h-btn-ghost{border-color:rgba(10,12,18,.20);font-weight:550}
.home-v4 .h-hero .h-btn-ghost:hover{border-color:var(--ink)}
/* A hairline of light along the top edge. It is what stops a flat black pill
   looking like a rectangle with rounded corners. */
.home-v4 .h-hero .h-btn-primary{
  box-shadow:var(--sh-2),inset 0 1px 0 rgba(255,255,255,.14);
}
.home-v4 .h-hero .h-btn-primary:hover{
  box-shadow:var(--sh-3),inset 0 1px 0 rgba(255,255,255,.18);
}
.home-v4 .center .h-btns{justify-content:center}

/* Focus that is actually visible, on both grounds. The old page inherited the
   browser default, which disappears entirely against the dark sections. */
.home-v4 a:focus-visible,.home-v4 button:focus-visible,.home-v4 input:focus-visible{
  outline:2px solid var(--violet);outline-offset:3px;border-radius:6px;
}
.home-v4 .h-night a:focus-visible,.home-v4 .h-night input:focus-visible{outline-color:var(--violet-3)}

/* ═══════════════ 1 · hero ═══════════════ */

/* THE FOLD. Everything below sizes off viewport HEIGHT as well as width, because
   the hero's job is to be seen without scrolling and width alone cannot know
   that. On a 1440x768 laptop, which is the common tight case, the section ran
   861px against 693px of usable space and overflowed by 168px: 213px of that
   was section padding and most of the rest was a 76px headline wrapping to four
   lines.

   min(Xvw, Yvh) is the mechanism throughout. On a tall window the width term
   wins and nothing changes; on a short one the height term takes over and the
   type, the padding and the card all come down together, in proportion. */
.home-v4 .h-hero{
  position:relative;overflow:hidden;
  padding:clamp(24px,min(7vw,4.7vh),96px) 0 clamp(28px,min(8vw,4.9vh),104px);
  min-height:calc(100svh - var(--hdr));
  display:flex;align-items:center;
}
.home-v4 .h-hero > .wrap{width:100%}
/* One soft light source from above, instead of three drifting blobs. */
.home-v4 .h-hero::before{
  content:'';position:absolute;inset:-30% -20% auto -20%;height:80%;pointer-events:none;
  background:radial-gradient(46% 56% at 50% 0%,rgba(108,92,231,.11),transparent 68%);
}
.home-v4 .h-hero .wrap{position:relative;z-index:1}
.home-v4 .h-hero-grid{
  display:grid;grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr);
  gap:clamp(36px,5vw,72px);align-items:center;
}
.home-v4 .h-hero-vis{min-width:0}
/* A ceiling on the measure, not a set of hard breaks. Balance handles where the
   lines fall; this only stops the headline running wider than it should. */
.home-v4 .h-hero h1{max-width:11.5em;margin-bottom:var(--s-4)}

/* The serif phrase takes its own line, always.
   text-wrap:balance optimises for even line LENGTHS, and left to itself it broke
   this headline as "The store AI / recommends / is the one / it can read": four
   lines, with "is" stranded in front of the serif and the serif phrase split in
   half. Even lengths, bad reading. Making the span a block moves the break to
   the one place the sentence actually has a joint, so it reads
   "The store AI / recommends is / the one it can read". */
.home-v4 .h-hero h1 .serif{display:block;padding-right:0;font-size:.92em}
/* .92em is measured: the phrase wants 569px on one line and the column gives
   534, so at full size it broke as "the one it / can read" and split the one
   phrase on the page that should arrive whole. An italic serif also reads
   optically larger than a bold sans at the same size, so stepping it back a
   little looks deliberate rather than reduced. */

/* Two beats, not one block. The first names what is at stake and stays in the
   quieter lead grey; the second is the answer, so it is a step brighter and
   carries a short accent rule to mark it as the reply rather than more of the
   same sentence. Tight gap between them, because they are one thought in two
   parts and a full paragraph break would read as two topics. */
.home-v4 .h-hero .lead{max-width:44ch;margin-bottom:var(--s-2)}
.home-v4 .h-lead-b{
  position:relative;max-width:44ch;
  padding-left:15px;margin-bottom:var(--s-5);
  font-size:clamp(16px,1.4vw,18.5px);line-height:1.55;
  letter-spacing:-.009em;color:var(--ink-2);text-wrap:pretty;
}
.home-v4 .h-lead-b::before{
  content:'';position:absolute;left:0;top:.42em;bottom:.42em;width:2px;
  border-radius:2px;background:var(--violet);opacity:.55;
}
.home-v4 .h-night .h-lead-b,.home-v4 .on-night .h-lead-b{color:#9BA2B4}
.home-v4 .h-hero .h-btns{margin-bottom:var(--s-4)}

/* Availability line — a small, specific, checkable claim beats a slogan. */
.home-v4 .h-avail{
  display:flex;align-items:center;flex-wrap:wrap;gap:8px 18px;
  list-style:none;margin:0;padding:0;
  font-size:13.5px;color:var(--ink-3);letter-spacing:-.005em;
}
.home-v4 .h-avail li{display:inline-flex;align-items:center;gap:7px;white-space:nowrap}
.home-v4 .h-avail li svg{flex:none;opacity:.55}
/* Only on the live-catalogue claim, which is the one it is about. */
.home-v4 .h-avail-live i{
  width:7px;height:7px;border-radius:50%;background:var(--mint);flex:none;
  box-shadow:0 0 0 3px rgba(58,223,165,.18);
}

/* ---- the outcome card ----
   Was a mock of Citelx's own dashboard, chrome and all. That made the page
   ambiguous about what is being sold: an agency, or software. This shows the
   result instead — an engine citing the store — and the engine row carries the
   breadth ("every engine, not just one") in a single readable line. */

/* No stack behind the card. Two darker layers used to peek out above it, to
   say "one answer of many"; the owner asked for them to go (2026-09-26): the
   corners showing at the top read as clutter, not depth. */
.home-v4 .h-hero-vis{position:relative}

.home-v4 .h-out{
  position:relative;z-index:1;
  border-radius:var(--r-xl);
  /* Not a flat fill. The gradient plus a coloured halo is most of the
     difference between "a dark box" and "a lit object". */
  background:linear-gradient(158deg,#1A1730,#0D0B1A 62%);
  border:1px solid rgba(255,255,255,.11);
  box-shadow:
    var(--sh-4),
    0 0 0 1px rgba(108,92,231,.14),
    0 26px 80px -24px rgba(108,92,231,.55),
    0 10px 120px -40px rgba(34,193,220,.40);
  padding:clamp(18px,2.4vh,26px);overflow:hidden;
}
.home-v4 .h-out::before{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(160deg,rgba(255,255,255,.08),transparent 36%);
}
.home-v4 .h-out > *{position:relative}

.home-v4 .h-out-q{
  display:flex;align-items:center;gap:10px;
  font-size:14.5px;color:#AEB5C6;
  padding-bottom:16px;margin-bottom:16px;
  border-bottom:1px solid rgba(255,255,255,.09);
}
.home-v4 .h-out-q svg{flex:none;opacity:.75}

/* ---- the rotating surface panel ----
   A fixed min-height holds the card steady as panels swap; without it the
   engine chips below jump every few seconds, which is the exact layout-shift
   problem the old rotating headline had.

   The value tracks the TALLEST panel, and it has to be a clamp rather than a
   fixed number because the panels themselves are now viewport-height aware: the
   answer type shrinks on a short window, so the tallest panel shrinks with it.
   Pinned at 422px it was forcing 58px of dead space into the card on a 768px
   laptop, which is the exact screen where the hero has no space to give.

   THIS CLAMP IS THE NO-JS FALLBACK ONLY. home.js measures the tallest panel and
   pins this element to it exactly, on load and on resize, because panel height
   depends on card width and window height together and no single ratio tracks
   both. Without JS nothing rotates, so an approximate floor is harmless. The 440px ceiling covers tall windows, where width caps the type
   anyway. RE-MEASURE all of this whenever a surface gains or loses a row: set
   too low and the rule silently stops working, which is how it once sat at
   262px underneath every panel doing nothing. */
.home-v4 .h-pans{
  background:rgba(108,92,231,.11);border:1px solid rgba(139,124,255,.24);
  border-radius:var(--r);padding:15px 17px;
  min-height:clamp(300px,50vh,452px);display:flex;flex-direction:column;
}
.home-v4 .h-pan[hidden]{display:none!important}
.home-v4 .h-pan{animation:h-panin .42s var(--ease-out);display:flex;flex-direction:column;flex:1}
@keyframes h-panin{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}

/* -- BEFORE / AFTER --
   The hero used to show one state: an answer that already named the store.
   That is the end of the story, so a visitor arriving cold saw a screenshot of
   something working and had no way to tell what had changed or why it mattered.
   Each panel now holds both states and plays the change: the same question,
   answered first without this store in it, then with it as the named source.

   The two states are stacked in one grid cell so the card never changes height
   mid-transition. A hero that jumps by 40px every three seconds is the single
   most distracting thing a page can do above the fold. */
.home-v4 .h-pan-top{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.home-v4 .h-ba{display:grid;flex:1}
.home-v4 .h-ba-s{
  grid-area:1/1;
  display:flex;flex-direction:column;
  /* Centred, not bottom-pinned. The container is sized for the TALLEST surface,
     so every shorter one has slack to place somewhere. Pinning the verdict line
     to the bottom put all of it in one lump between the source chips and that
     line: a 60px hole in the middle of the card, which reads as a missing
     element. Centred, the same slack splits above and below and reads as the
     card being generously set. */
  justify-content:center;
  transition:opacity .5s var(--ease),transform .5s var(--ease);
}
.home-v4 .h-pan[data-state="was"] .h-ba-now,
.home-v4 .h-pan[data-state="now"] .h-ba-was{
  opacity:0;pointer-events:none;transform:translateY(-6px);
}
.home-v4 .h-pan[data-state="now"] .h-ba-now{transform:none}
.home-v4 .h-pan[data-state="was"] .h-ba-was{transform:none}

/* The before state is deliberately flat: no highlight, no check, no accent.
   It has to read as the ordinary result a store gets today. */
.home-v4 .h-ba-was p{color:#8B93A7}
.home-v4 .h-ba-was .h-chip{opacity:.72}

/* The verdict line. This is the sentence doing the persuading, so it is the
   one element that changes colour between states rather than just position. */
.home-v4 .h-ba-miss,.home-v4 .h-ba-hit{
  display:flex;align-items:center;gap:8px;
  padding-top:14px;
  font-size:12.5px;letter-spacing:-.004em;
}
.home-v4 .h-ba-miss{color:#8B93A7}
.home-v4 .h-ba-hit{color:var(--mint)}
.home-v4 .h-ba-miss i,.home-v4 .h-ba-hit i{
  width:6px;height:6px;border-radius:50%;flex:none;
}
.home-v4 .h-ba-miss i{background:#5A6172}
.home-v4 .h-ba-hit i{background:var(--mint);box-shadow:0 0 0 3px rgba(58,223,165,.20)}

/* State badge, top right of the card. */
/* Readability, not contrast. Dark ink on mint is already a strong pairing; what
   made this hard to read was 10px monospace, uppercased, tracked out to .11em.
   Each of those costs legibility on its own and the three together are the worst
   combination available at this size. Bigger, heavier, tighter, and in the UI
   face rather than the mono one, which is drawn for columns of code and not for
   a two-word badge. */
.home-v4 .h-ba-lab{
  display:inline-flex;align-items:center;gap:5px;margin-left:auto;
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:11.5px;font-weight:700;letter-spacing:.045em;text-transform:uppercase;
  padding:5px 11px;border-radius:99px;white-space:nowrap;line-height:1;
  transition:opacity .35s var(--ease);
}
.home-v4 .h-ba-lab.was{color:#7E8698;background:rgba(255,255,255,.06)}
.home-v4 .h-ba-lab.now{color:#05100C;background:var(--mint)}
.home-v4 .h-ba-lab.now svg{stroke-width:2.6}
.home-v4 .h-pan[data-state="was"] .h-ba-lab.now,
.home-v4 .h-pan[data-state="now"] .h-ba-lab.was{display:none}

@media (prefers-reduced-motion:reduce){
  .home-v4 .h-ba-s{transition:none}
}
.home-v4 .h-out-tag{
  display:flex;align-items:center;gap:7px;
  font-family:'IBM Plex Mono',monospace;font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--violet-3);margin-bottom:10px;
}
/* The answer is the thing being sold, and it was set at 14.5px: smaller than
   the lead paragraph next to it, in a dimmer grey. It now reads as a statement.
   This single change does more for the hero than any amount of animation. */
.home-v4 .h-pan p{
  font-size:clamp(14.5px,min(1.75vw,2.15vh),22px);line-height:1.45;
  letter-spacing:-.014em;color:#EDEFF5;margin-bottom:14px;text-wrap:pretty;
}
.home-v4 .h-pan sup{font-size:9px;color:var(--violet-3);vertical-align:super}
/* The citation itself — the whole promise of the page, so it is the one thing
   in the hero visual that gets a colour. */
.home-v4 .h-pan mark{
  color:#fff;font-weight:600;
  padding:2px 7px;border-radius:6px;
  background-image:linear-gradient(90deg,rgba(34,193,220,.92),rgba(139,124,255,.92));
  background-repeat:no-repeat;background-position:0 0;background-size:100% 100%;
  box-shadow:0 0 26px rgba(34,193,220,.38);
}
/* It sweeps in when the answer flips to the cited state, left to right, like a
   highlighter. The moment the store's name lights up is the one thing in this
   hero worth animating. */
.home-v4 .h-pan[data-state="now"] .h-ba-now mark{animation:h-cite .62s var(--ease-out) .12s both}
@keyframes h-cite{
  from{background-size:0 100%}
  to{background-size:100% 100%}
}
@media (prefers-reduced-motion:reduce){
  .home-v4 .h-pan[data-state="now"] .h-ba-now mark{animation:none}
}
/* No margin-top:auto. It pushed the source chips to the bottom of the panel,
   which was the actual source of the hole in the middle of the card: centring
   the block above only moved the slack, because an auto margin beats
   justify-content and kept claiming all of it. The chips now sit where they
   belong, directly under the answer they belong to. */
.home-v4 .h-pan-src{display:flex;flex-wrap:wrap;gap:6px}
.home-v4 .h-pan-src .h-chip{
  background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.09);color:#8A91A4;
}
.home-v4 .h-pan-src .h-chip.win{
  background:rgba(34,193,220,.14);border-color:rgba(34,193,220,.42);color:#fff;font-weight:550;
}

/* YouTube-style result rows */
/* -- YouTube --
   A search result on YouTube is a 16:9 thumbnail with a duration burned into
   its corner, a title, then channel and views on one grey line. The thumbnail
   was 52x32 with nothing on it, which is a grey rectangle rather than a video,
   and the row was carded up in a way YouTube never does. Rows are transparent
   now, thumbnails are proper 16:9, and the duration badge is what makes the
   block read as video at a glance. */
.home-v4 .h-vres{display:flex;flex-direction:column;gap:11px}
.home-v4 .h-vrow{display:flex;align-items:flex-start;gap:11px}
.home-v4 .h-vrow i{
  position:relative;width:88px;aspect-ratio:16/9;border-radius:8px;flex:none;
  background:linear-gradient(140deg,rgba(255,255,255,.15),rgba(255,255,255,.05));
  overflow:hidden;
}
.home-v4 .h-vrow u{
  position:absolute;right:4px;bottom:4px;
  padding:1px 4px;border-radius:3px;text-decoration:none;
  font-size:9.5px;font-weight:600;letter-spacing:.01em;
  color:#fff;background:rgba(0,0,0,.72);
}
.home-v4 .h-vrow span{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}
.home-v4 .h-vrow b{
  font-size:13px;font-weight:550;color:#F1F1F1;line-height:1.28;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.home-v4 .h-vrow em{font-style:normal;font-size:11px;color:#AAAAAA;line-height:1.3}
.home-v4 .h-vrow svg{color:var(--mint);flex:none;margin-top:3px}
/* YouTube's own red, on the one row that is the store's. */
.home-v4 .h-vrow.win i{background:linear-gradient(140deg,rgba(255,78,69,.55),rgba(200,30,40,.42))}
.home-v4 .h-vrow.win b{color:#fff}
.home-v4 .h-vrow.win{background:rgba(34,193,220,.12);border-color:rgba(34,193,220,.35)}
.home-v4 .h-vrow.win i{background:linear-gradient(140deg,rgba(34,193,220,.42),rgba(108,92,231,.34))}
.home-v4 .h-vrow.win b{color:#fff}
.home-v4 .h-vrow.win em{color:var(--cyan)}

/* TikTok-style vertical clips */
/* -- TikTok --
   Portrait, not square. A 9:16 tile with the play count burned into the bottom
   left is the single most recognisable thing about that feed, and square tiles
   made this panel identical to Pinterest's. */
.home-v4 .h-clips{display:grid;grid-template-columns:repeat(3,1fr);gap:9px}
.home-v4 .h-clip{display:flex;flex-direction:column;gap:5px;min-width:0}
.home-v4 .h-clip i{
  display:block;aspect-ratio:9/14;border-radius:8px;
  background:linear-gradient(150deg,rgba(255,255,255,.13),rgba(255,255,255,.04));
}
.home-v4 .h-clip.win i{
  background:linear-gradient(150deg,rgba(63,231,224,.42),rgba(254,44,85,.34));
}
.home-v4 .h-clip b{
  font-size:11px;font-weight:500;color:#B9BFCC;line-height:1.3;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.home-v4 .h-clip em{
  font-style:normal;font-size:10px;color:#8B93A7;
  display:flex;align-items:center;gap:4px;
}
.home-v4 .h-clip em::before{
  content:'';width:0;height:0;flex:none;
  border-left:5px solid currentColor;
  border-top:3.5px solid transparent;border-bottom:3.5px solid transparent;
}
.home-v4 .h-clip.win i{background:linear-gradient(150deg,rgba(34,193,220,.40),rgba(108,92,231,.34))}
.home-v4 .h-clip.win b{color:#fff}

/* -- Google --
   Quoting another interface, so it borrows that interface's palette rather than
   this theme's. #8AB4F8 is the link blue Google actually ships in dark mode and
   it is the single strongest recognition cue on the panel: a blue title over a
   breadcrumb URL over a grey snippet is a Google result before you read a word
   of it. The AI Overview keeps its own tinted container above that, which is
   how Google separates the generated answer from the ten blue links. */
.home-v4 .h-goog{display:flex;flex-direction:column;gap:14px}

.home-v4 .h-goog-ao{
  border-radius:12px;padding:12px 14px 13px;
  background:rgba(138,180,248,.07);
  border:1px solid rgba(138,180,248,.16);
  transition:background .35s var(--ease),border-color .35s var(--ease);
}
.home-v4 .h-goog-ao.on{
  background:linear-gradient(125deg,rgba(138,180,248,.16),rgba(198,160,255,.12));
  border-color:rgba(138,180,248,.34);
}
.home-v4 .h-goog-ao-h{
  display:flex;align-items:center;gap:6px;margin-bottom:8px;
  font-size:11.5px;font-weight:600;letter-spacing:.01em;color:#A8C7FA;
}
.home-v4 .h-goog-ao-h svg{flex:none}
.home-v4 .h-goog-ao p{
  font-size:15px!important;line-height:1.5;margin:0 0 10px!important;color:#E3E6EC;
}

/* The source cards Google stacks under an overview. The dot stands in for a
   favicon: a real one would mean shipping six site icons for a mock. */
.home-v4 .h-goog-cites{display:flex;flex-wrap:wrap;gap:6px}
.home-v4 .h-goog-cite{
  display:inline-flex;align-items:center;gap:6px;
  padding:4px 9px;border-radius:8px;
  font-size:10.5px;color:#9AA0A6;
  background:rgba(255,255,255,.05);
  border:1px solid rgba(255,255,255,.08);
}
.home-v4 .h-goog-cite i{width:9px;height:9px;border-radius:2px;background:#5F6368;flex:none}
.home-v4 .h-goog-cite.win{
  color:#E8EAED;background:rgba(138,180,248,.18);border-color:rgba(138,180,248,.45);
}
.home-v4 .h-goog-cite.win i{background:linear-gradient(140deg,#8AB4F8,#C6A0FF)}

/* One organic result. Blue title, breadcrumb URL, grey snippet, in that order,
   because that order is the thing being recognised. */
.home-v4 .h-goog-res{display:flex;flex-direction:column;gap:3px}
.home-v4 .h-goog-url{
  display:flex;align-items:center;gap:7px;
  font-size:11.5px;color:#BDC1C6;letter-spacing:-.002em;
}
.home-v4 .h-goog-url i{
  width:14px;height:14px;border-radius:50%;flex:none;
  background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.14);
}
.home-v4 .h-goog-res.on .h-goog-url i{background:linear-gradient(140deg,#8AB4F8,#C6A0FF);border-color:transparent}
.home-v4 .h-goog-t{
  font-size:15.5px;line-height:1.28;letter-spacing:-.012em;
  color:#8AB4F8;font-weight:400;
}
.home-v4 .h-goog-sn{
  font-size:12.5px!important;line-height:1.45;margin:0!important;color:#9AA0A6;
}

/* -- Pinterest --
   Masonry is the whole visual signature: tiles of unequal height in columns,
   which is why a Pinterest board is recognisable from across a room. Rendered
   as equal tiles it was indistinguishable from the TikTok panel, so the tiles
   now take three different heights and the corners are rounder than anything
   else on the page. The metric is saves, not views, because that is what the
   platform counts. */
.home-v4 .h-pins{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:9px;align-items:start;
}
.home-v4 .h-pin{display:flex;flex-direction:column;gap:6px;min-width:0}
.home-v4 .h-pin i{
  display:block;border-radius:14px;
  background:linear-gradient(150deg,rgba(255,255,255,.13),rgba(255,255,255,.04));
}
/* The staggered heights. Three values, so no two neighbours match. */
.home-v4 .h-pin:nth-child(1) i{aspect-ratio:3/4}
.home-v4 .h-pin:nth-child(2) i{aspect-ratio:3/5}
.home-v4 .h-pin:nth-child(3) i{aspect-ratio:1}
.home-v4 .h-pin b{
  font-size:11px;font-weight:500;color:#B9BFCC;line-height:1.3;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.home-v4 .h-pin em{
  font-style:normal;font-size:10px;color:#8B93A7;
  display:flex;align-items:center;gap:4px;
}
.home-v4 .h-pin em svg{flex:none;opacity:.8}
/* Pinterest red on the store's pin. */
.home-v4 .h-pin.win i{
  background:linear-gradient(150deg,rgba(230,0,35,.52),rgba(255,120,140,.34));
  box-shadow:0 0 0 2px rgba(230,0,35,.45);
}
.home-v4 .h-pin.win b{color:#fff}
.home-v4 .h-pin.win em{color:#FF8FA0}

/* -- Meta AI --
   The one surface that is two surfaces. Meta AI is not a page you visit, it
   answers inside Instagram and Facebook, so the panel shows the apps by their
   own marks, the feed underneath them, and the assistant reply last. Drawn in
   that order because that is the order a person meets it: they are in the app
   first, and the AI speaks second. */
.home-v4 .h-meta{display:flex;flex-direction:column;gap:11px}
/* Slightly wider than square. Meta's own feeds crop to portrait, but three
   portrait tiles plus a reply made this panel 411px against 267 for its
   neighbours, and a card that grows 140px when the rotation reaches it is the
   layout shift the whole rotation was built to avoid. */
.home-v4 .h-meta-grid .h-clip i{aspect-ratio:1.28}

/* The app marks sit with the reply rather than on a row of their own: they are
   identifying who is speaking, which is what a name badge on a message does. */
.home-v4 .h-meta-apps{display:flex;align-items:center;gap:6px;margin-bottom:7px}
.home-v4 .h-meta-apps svg{flex:none}
.home-v4 .h-meta-apps b{
  font-size:11px;font-weight:650;letter-spacing:.02em;color:#AEB5C6;margin-left:2px;
}
.home-v4 .h-meta-ai.on .h-meta-apps b{color:#F2F4F9}

/* The assistant reply. Set as a bubble rather than a paragraph so it reads as
   something said inside an app, which is the whole difference between this
   panel and the two answer panels above it. */
.home-v4 .h-meta-ai{
  border-radius:12px;padding:11px 13px;
  background:rgba(255,255,255,.045);
  border:1px solid rgba(255,255,255,.08);
  transition:background .35s var(--ease),border-color .35s var(--ease);
}
.home-v4 .h-meta-ai.on{
  background:linear-gradient(120deg,rgba(108,92,231,.20),rgba(34,193,220,.13));
  border-color:rgba(139,124,255,.34);
}
.home-v4 .h-meta-ask{
  display:block;margin-bottom:5px;
  font-family:'IBM Plex Mono',monospace;
  font-size:10.5px;letter-spacing:.02em;color:#7E8698;
}
.home-v4 .h-meta-ai p{
  font-size:14.5px!important;line-height:1.45;margin:0!important;color:#DCDFE8;
}
.home-v4 .h-meta-ai.on p{color:#F2F4F9}
.home-v4 .h-clip.win em{color:var(--cyan)}

.home-v4 .h-eng{margin-top:18px}
.home-v4 .h-eng-lab{
  display:block;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  color:#6B7285;margin-bottom:10px;
}
.home-v4 .h-eng-list{display:flex;flex-wrap:wrap;gap:6px}
/* The chips are the tab control for the panel above, so they get real button
   affordances — cursor, hover, and a clearly different selected state. */
.home-v4 .h-eng-i{
  display:inline-flex;align-items:center;gap:6px;
  font:inherit;font-size:11.5px;color:#8A91A4;white-space:nowrap;
  padding:6px 10px;border-radius:99px;cursor:pointer;
  background:rgba(255,255,255,.045);border:1px solid rgba(255,255,255,.08);
  transition:background .18s var(--ease),border-color .18s var(--ease),color .18s var(--ease);
}
.home-v4 .h-eng-i:hover{background:rgba(255,255,255,.09);color:#D8DCE6}
.home-v4 .h-eng-i.on{
  background:rgba(139,124,255,.20);border-color:rgba(139,124,255,.52);color:#fff;
}
.home-v4 .h-eng-i svg:first-child{opacity:.7;flex:none}
.home-v4 .h-eng-i.on svg:first-child{opacity:1}
/* The tick marks the surface currently open, not every chip permanently.
   Five surfaces need 514px of a 453px row, and a tick plus its gap on all five
   is 85px of that: more than the overflow. It was also saying nothing, because
   the "Cited in" label above already makes the claim for the whole row. Used
   this way it earns its space and the chips fit on one line. */
.home-v4 .h-eng-i svg:last-child{display:none}
.home-v4 .h-eng-i.on svg:last-child{display:block;color:var(--mint);flex:none;opacity:.9}
.home-v4 .h-eng-i{padding:6px 9px}
/* Six surfaces will not fit one 453px line, and wrapping them leaves a ragged
   4 + 2. A three-column grid makes it a deliberate 3 + 3 instead, with every
   chip the same width, which reads as a set rather than as a row that ran out
   of space. Two columns on a phone for the same reason. */
.home-v4 .h-eng-list{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
.home-v4 .h-eng-i{justify-content:center;min-width:0}
@media (max-width:520px){
  .home-v4 .h-eng-list{grid-template-columns:repeat(2,1fr)}
  /* Three claims will not fit one 335px line, and wrapping strands the third.
     Stacked, each keeps its icon and reads as its own promise, which is what
     splitting them up was for. */
  .home-v4 .h-avail{flex-direction:column;align-items:flex-start;gap:7px}
}
.home-v4 .h-eng-i.on svg:last-child{opacity:1}

/* ═══════════════ 2 · the buying journey ═══════════════
   Six stops on one rail. The rail is the point: it says these are stages of a
   single purchase, not six unrelated channels. Each stop carries the platform's
   accent on its dot only — six saturated cards side by side would be a rainbow,
   one coloured dot each reads as a system. */

/* ---- the rotating platform in the headline ----
   Every word occupies the SAME grid cell, so the box is permanently as wide as
   the longest of them ("all six of them") and the line can never reflow as the
   word changes. This is the structural fix the old JS width-measuring hack was
   reaching for. */
.home-v4 .h-rot{
  display:inline-grid;
  vertical-align:top;
  text-align:center;
}
.home-v4 .h-rot-i{
  grid-area:1/1;
  color:var(--ac);
  white-space:nowrap;
  opacity:0;transform:translateY(.2em);
  /* Short enough that the word is fully legible for most of its 1.45s slot —
     a .42s fade against a 1.45s cadence spends a third of it mid-transition. */
  transition:opacity .22s var(--ease-out),transform .22s var(--ease-out);
}
.home-v4 .h-rot-i.on{opacity:1;transform:none}
/* The payoff line gets the brand gradient — it is the only word in the cycle
   that is not a platform, so it should not look like one. */
.home-v4 .h-rot-i.fin{
  background:linear-gradient(100deg,var(--violet),var(--cyan));
  -webkit-background-clip:text;background-clip:text;color:transparent;
}

/* The stop on the rail lights up in time with the headline. */
.home-v4 .h-fstop.is-live .h-fdot{
  transform:translateY(-3px) scale(1.1);
  background:color-mix(in srgb,var(--ac) 12%,var(--paper));
  border-color:var(--ac);
  box-shadow:0 0 0 5px var(--paper-2), 0 10px 26px color-mix(in srgb,var(--ac) 38%,transparent);
}
.home-v4 .h-fstop .h-fplat{transition:color .3s var(--ease)}
.home-v4 .h-fstop.is-live .h-fplat{color:var(--ac)}

.home-v4 .h-flow{
  display:grid;grid-template-columns:repeat(6,1fr);
  gap:clamp(10px,1.4vw,18px);
  position:relative;
}
/* The rail, threaded through the dots. Sits behind everything and stops short
   of the first and last dot so it reads as a path, not a border. */
.home-v4 .h-flow::before{
  content:'';position:absolute;z-index:0;
  left:8%;right:8%;top:48px;height:2px;
  background:linear-gradient(90deg,
    rgba(34,193,220,.5),rgba(255,92,138,.5),rgba(255,107,107,.5),
    rgba(108,92,231,.5),rgba(139,124,255,.5),rgba(184,169,255,.5));
  border-radius:2px;
}
.home-v4 .h-fstop{
  position:relative;z-index:1;
  display:flex;flex-direction:column;align-items:center;text-align:center;
  gap:var(--s-2);
}
.home-v4 .h-fstage{
  font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-4);height:14px;
}
.home-v4 .h-fdot{
  width:46px;height:46px;border-radius:50%;display:grid;place-items:center;
  color:var(--ac);background:var(--paper);
  border:2px solid color-mix(in srgb,var(--ac) 42%,transparent);
  box-shadow:0 0 0 5px var(--paper-2), 0 6px 18px color-mix(in srgb,var(--ac) 22%,transparent);
  transition:transform .3s var(--ease-out),box-shadow .3s var(--ease);
}
.home-v4 .h-fstop:hover .h-fdot{
  transform:translateY(-3px) scale(1.06);
  box-shadow:0 0 0 5px var(--paper-2), 0 12px 26px color-mix(in srgb,var(--ac) 34%,transparent);
}
.home-v4 .h-fplat{
  font-family:'Inter Tight',Inter,sans-serif;font-size:15px;font-weight:600;
  letter-spacing:-.022em;color:var(--ink);
}
/* The query, dressed as the search box it was typed into — the detail that
   makes the row read as six real searches rather than six labels. */
.home-v4 .h-fq{
  display:flex;align-items:center;gap:6px;
  width:100%;min-height:64px;
  padding:8px 10px;border-radius:9px;
  font-size:11.5px;line-height:1.35;color:var(--ink-2);text-align:left;
  background:var(--paper);border:1px solid var(--line-2);
}
.home-v4 .h-fq svg{flex:none;color:var(--ink-4)}
.home-v4 .h-fnote{font-size:12px;line-height:1.45;color:var(--ink-3);max-width:20ch}


/* ═══════════════ 3 · anatomy of one search result ═══════════════
   The results page itself, stacked. Each block is numbered and the numbers key
   into the legend beside it, so the visitor reads the picture and the argument
   together rather than one after the other. The last block is dimmed on
   purpose: the old organic #1 is the thing that lost its value. */

.home-v4 .h-serp-wrap{
  display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);
  gap:clamp(28px,4vw,56px);align-items:start;
}

.home-v4 .h-serp{
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-xl);
  padding:18px;box-shadow:var(--sh-2);
}
.home-v4 .h-serp-q{
  display:flex;align-items:center;gap:10px;
  font-size:13.5px;color:var(--ink-2);
  padding:12px 16px;margin-bottom:14px;
  background:var(--paper-2);border:1px solid var(--line-2);border-radius:99px;
}
.home-v4 .h-serp-q svg{flex:none;color:var(--ink-4)}

/* one result block */
.home-v4 .h-sb{
  position:relative;
  padding:14px 14px 14px 40px;
  border-radius:var(--r);
  border:1px solid var(--line-2);
  margin-bottom:8px;
  transition:border-color .22s var(--ease),background .22s var(--ease);
}
.home-v4 .h-sb:last-child{margin-bottom:0}
.home-v4 .h-sb:hover{border-color:color-mix(in srgb,var(--violet) 32%,transparent);background:rgba(108,92,231,.03)}
.home-v4 .h-sb-n{
  position:absolute;top:14px;left:12px;
  width:19px;height:19px;border-radius:6px;
  display:grid;place-items:center;
  font-family:'IBM Plex Mono',monospace;font-size:10.5px;font-weight:500;
  color:#fff;background:var(--ink);
}
.home-v4 .h-sb-t{
  display:flex;align-items:center;gap:7px;
  font-size:10.5px;font-family:'IBM Plex Mono',monospace;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);
  margin-bottom:9px;
}
.home-v4 .h-sb-t svg{flex:none;color:var(--violet)}
.home-v4 .h-sb-a{font-size:13.5px;line-height:1.55;color:var(--ink-2);margin-bottom:11px;min-height:2.9em}

/* source chips under the AI answer */
.home-v4 .h-sb-src{display:flex;flex-wrap:wrap;gap:6px}
.home-v4 .h-chip{
  display:inline-flex;align-items:center;gap:5px;
  font-size:11.5px;color:var(--ink-3);
  padding:5px 10px;border-radius:99px;
  background:var(--paper-2);border:1px solid var(--line-2);
}
.home-v4 .h-chip.win{
  color:var(--ink);font-weight:550;
  background:rgba(34,193,220,.10);border-color:rgba(34,193,220,.42);
}
.home-v4 .h-chip.win svg{color:var(--cyan);flex:none}

/* video carousel — tinted per platform, because the colour is the information */
.home-v4 .h-vids{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.home-v4 .h-vid{display:flex;flex-direction:column;gap:5px;min-width:0}
.home-v4 .h-vid i{
  display:block;height:48px;border-radius:8px;
  border:1px solid rgba(10,12,18,.05);
  background:linear-gradient(145deg,var(--paper-3),#DDE1EC);
}
.home-v4 .h-vid b{font-size:11.5px;font-weight:550;color:var(--ink-2);line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.home-v4 .h-vid em{font-style:normal;font-size:10.5px;color:var(--ink-4)}
.home-v4 .h-vid.yt i{background:linear-gradient(145deg,rgba(255,107,107,.34),rgba(255,107,107,.12))}
.home-v4 .h-vid.tt i{background:linear-gradient(145deg,rgba(34,193,220,.34),rgba(34,193,220,.12))}
.home-v4 .h-vid.ig i{background:linear-gradient(145deg,rgba(255,92,138,.30),rgba(184,169,255,.28))}
.home-v4 .h-vid.win i{
  background:linear-gradient(145deg,var(--violet),var(--cyan));
  border-color:transparent;
  box-shadow:0 4px 14px rgba(108,92,231,.28);
}
.home-v4 .h-vid.win b{color:var(--ink)}
.home-v4 .h-vid.win em{color:var(--cyan);font-weight:600}

/* image pack — Pinterest's ground, with Instagram alongside it */
.home-v4 .h-imgs{display:grid;grid-template-columns:repeat(6,1fr);gap:7px}
.home-v4 .h-img{display:flex;flex-direction:column;gap:5px;min-width:0}
.home-v4 .h-img i{
  display:block;aspect-ratio:1;border-radius:8px;
  border:1px solid rgba(10,12,18,.05);
  background:var(--paper-3);
}
.home-v4 .h-img em{
  font-style:normal;font-size:9.5px;color:var(--ink-4);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.home-v4 .h-img.pin i{background:linear-gradient(150deg,rgba(255,92,138,.34),rgba(255,92,138,.10))}
.home-v4 .h-img.ig i{background:linear-gradient(150deg,rgba(184,169,255,.36),rgba(255,92,138,.16))}
.home-v4 .h-img.win i{
  background:linear-gradient(150deg,var(--violet),var(--cyan));
  border-color:transparent;
  box-shadow:0 4px 14px rgba(108,92,231,.28);
}
.home-v4 .h-img.win em{color:var(--cyan);font-weight:600}

/* people also ask */
.home-v4 .h-paa{display:flex;flex-direction:column;gap:6px}
.home-v4 .h-paa span{
  display:flex;align-items:center;justify-content:space-between;
  font-size:12.5px;color:var(--ink-2);
  padding:9px 12px;border-radius:8px;background:var(--paper-2);
}
.home-v4 .h-paa span::after{
  content:'';width:7px;height:7px;flex:none;
  border-right:1.5px solid var(--ink-4);border-bottom:1.5px solid var(--ink-4);
  transform:rotate(45deg) translateY(-2px);
}

/* the old blue link */
.home-v4 .h-sb.dim{opacity:.55;border-style:dashed}
.home-v4 .h-sb.dim .h-sb-n{background:var(--ink-4)}
.home-v4 .h-blue b{display:block;font-size:14px;font-weight:550;color:#1A0DAB;letter-spacing:-.01em}
.home-v4 .h-blue span{display:block;font-size:11.5px;color:var(--ink-3);margin-top:2px}
.home-v4 .h-fold{display:block;margin-top:11px;font-size:10.5px;color:var(--ink-4)}

/* the numbered legend */
.home-v4 .h-legend{list-style:none;counter-reset:sb;padding:0;position:sticky;top:100px}
.home-v4 .h-legend li{
  counter-increment:sb;position:relative;
  padding:16px 0 16px 38px;border-bottom:1px solid var(--line-2);
}
.home-v4 .h-legend li:first-child{padding-top:0}
.home-v4 .h-legend li:last-child{border-bottom:0;padding-bottom:0}
.home-v4 .h-legend li::before{
  content:counter(sb);position:absolute;left:0;top:16px;
  width:22px;height:22px;border-radius:7px;
  display:grid;place-items:center;
  font-family:'IBM Plex Mono',monospace;font-size:11px;font-weight:500;
  color:var(--ink-2);background:var(--paper-2);border:1px solid var(--line-2);
}
.home-v4 .h-legend li:first-child::before{top:0}
.home-v4 .h-legend b{display:block;font-size:16px;font-weight:600;letter-spacing:-.02em;color:var(--ink);margin-bottom:5px}
.home-v4 .h-legend p{font-size:14px;line-height:1.55;color:var(--ink-2)}

/* ═══════════════ 4 · surfaces ═══════════════ */
/* Was a rotating orbit. Nine links that moved continuously and rendered their
   labels upside-down for half of every revolution. Now a grid you can read. */

.home-v4 .h-surf{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:1px;background:var(--line-2);
  border:1px solid var(--line-2);border-radius:var(--r-lg);overflow:hidden;
}
.home-v4 .h-surf-i{
  display:flex;flex-direction:column;gap:var(--s-2);
  padding:clamp(20px,2.4vw,28px);background:var(--paper);position:relative;
  transition:background .22s var(--ease);
}
.home-v4 .h-surf-i:hover{background:var(--paper-2)}
.home-v4 .h-surf-i .ico{
  color:var(--ink-3);transition:color .22s var(--ease),transform .34s var(--ease-out);
}
.home-v4 .h-surf-i:hover .ico{color:var(--ac,var(--violet));transform:translateY(-2px)}
.home-v4 .h-surf-i h3{font-size:17px;letter-spacing:-.02em}
.home-v4 .h-surf-i p{font-size:14px;line-height:1.5;color:var(--ink-3)}
.home-v4 .h-surf-i .h-go{
  display:flex;align-items:center;gap:6px;margin-top:auto;padding-top:var(--s-2);
  font-size:13px;font-weight:550;color:var(--ink-4);
  transition:color .2s var(--ease);
}
.home-v4 .h-surf-i:hover .h-go{color:var(--ac,var(--violet))}
.home-v4 .h-surf-i .h-go svg{width:15px;height:15px;transition:transform .26s var(--ease-out)}
.home-v4 .h-surf-i:hover .h-go svg{transform:translateX(3px)}
/* The accent as a top edge that draws in — one line, one colour, on hover. */
.home-v4 .h-surf-i::after{
  content:'';position:absolute;top:0;left:0;right:0;height:2px;
  background:var(--ac,var(--violet));transform:scaleX(0);transform-origin:left;
  transition:transform .38s var(--ease-out);
}
.home-v4 .h-surf-i:hover::after{transform:scaleX(1)}

.home-v4 .h-surf-note{
  margin-top:var(--s-4);font-size:13.5px;color:var(--ink-3);text-align:center;
}

/* ═══════════════ short windows ═══════════════
   A 1366x768 laptop gives roughly 700px of viewport once browser chrome is
   taken out, and that is a mainstream screen, not an edge case. The hero is
   meant to sit inside one screen, and at that height the answer card is what
   does not fit: the type already scales with vh, but the SPACING does not, and
   spacing is most of a card's height.

   So the gaps close before anything else gives. Nothing is hidden and no line
   is dropped; the card simply gets denser, which is the right trade at a size
   where the alternative is the call to action falling below the fold. */
@media (max-height:790px) and (min-width:721px){
  .home-v4 .h-out{padding:15px}
  .home-v4 .h-out-q{padding-bottom:11px;margin-bottom:11px}
  .home-v4 .h-pans{padding:12px 13px}
  .home-v4 .h-pan-top{margin-bottom:9px}

  .home-v4 .h-goog{gap:9px}
  .home-v4 .h-goog-ao{padding:9px 11px 10px}
  .home-v4 .h-goog-ao p{margin-bottom:7px!important}
  .home-v4 .h-goog-ao-h{margin-bottom:5px}

  .home-v4 .h-meta{gap:8px}
  .home-v4 .h-meta-ai{padding:8px 10px}
  .home-v4 .h-vres{gap:8px}
  .home-v4 .h-ba-miss,.home-v4 .h-ba-hit{padding-top:9px}
  .home-v4 .h-eng{margin-top:11px}
  .home-v4 .h-eng-list{gap:5px}
  .home-v4 .h-eng-i{padding:5px 8px;font-size:11px}
}

/* ═══════════════ 7 · services ═══════════════ */

.home-v4 .h-svc{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,1.6vw,18px)}
.home-v4 .h-svc-i{
  display:flex;flex-direction:column;
  background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r-lg);
  padding:clamp(22px,2.4vw,28px);position:relative;overflow:hidden;
  transition:transform .3s var(--ease-out),box-shadow .3s var(--ease),border-color .3s var(--ease);
}
.home-v4 .h-svc-i:hover{
  transform:translateY(-3px);
  border-color:color-mix(in srgb,var(--ac) 26%,transparent);
  box-shadow:0 18px 44px color-mix(in srgb,var(--ac) 14%,transparent);
}
.home-v4 .h-svc-ic{
  width:44px;height:44px;border-radius:13px;display:grid;place-items:center;
  color:var(--ac);background:color-mix(in srgb,var(--ac) 8%,var(--paper));
  border:1px solid color-mix(in srgb,var(--ac) 18%,transparent);
  margin-bottom:var(--s-4);flex:none;
  transition:transform .34s var(--ease-out);
}
.home-v4 .h-svc-i:hover .h-svc-ic{transform:scale(1.06) rotate(-4deg)}
.home-v4 .h-svc-i h3{margin-bottom:8px}
.home-v4 .h-svc-i p{font-size:14.5px;line-height:1.55;margin-bottom:var(--s-4)}
.home-v4 .h-svc-i .h-go{
  display:flex;align-items:center;gap:6px;margin-top:auto;
  font-size:13.5px;font-weight:550;color:var(--ac);
}
.home-v4 .h-svc-i .h-go svg{width:15px;height:15px;transition:transform .26s var(--ease-out)}
.home-v4 .h-svc-i:hover .h-go svg{transform:translateX(3px)}

/* The full-stack tile — the one card that is deliberately different. */
.home-v4 .h-svc-all{
  background:var(--night);border-color:transparent;color:#fff;
  justify-content:space-between;
}
.home-v4 .h-svc-all h3{color:#fff}
.home-v4 .h-svc-all p{color:#9BA2B4}
.home-v4 .h-svc-all .h-svc-ic{
  color:#fff;background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.14);
}
.home-v4 .h-svc-all .h-go{color:#fff}
.home-v4 .h-svc-all:hover{box-shadow:var(--sh-3)}

/* ═══════════════ 8 · closing CTA ═══════════════ */

/* Light, and shorter. It was inheriting --sec-y, up to 140px top AND bottom,
   which left a screen's worth of empty dark below a one-line form. This section
   is a single action; it does not need the breathing room a content section
   does. Own padding, roughly 40% of what it had.

   Everything below re-states what .h-night used to provide, because the scan
   bar was drawn for a dark ground: white-on-white input text is exactly how the
   app theme's light conversion failed earlier. .h-btn-primary and .label needed
   nothing — their defaults were already the light ones. */
.home-v4 .h-cta{
  position:relative;overflow:hidden;text-align:center;
  padding:clamp(54px,6vw,84px) 0;
  background:linear-gradient(180deg,var(--paper),var(--paper-2));
  border-top:1px solid var(--line-2);
}
.home-v4 .h-cta::before{
  content:'';position:absolute;inset:auto -20% -60% -20%;height:90%;pointer-events:none;
  background:radial-gradient(50% 60% at 50% 100%,rgba(108,92,231,.12),transparent 70%);
}
.home-v4 .h-cta .wrap{position:relative;z-index:1}
.home-v4 .h-cta-in{max-width:640px;margin-inline:auto}
.home-v4 .h-cta h2{margin-bottom:12px;color:var(--ink)}
.home-v4 .h-cta .lead{color:var(--ink-2);margin-bottom:26px}

.home-v4 .h-scan{
  display:flex;gap:8px;padding:7px;border-radius:99px;max-width:470px;margin-inline:auto;
  background:var(--paper);border:1px solid var(--line);
  box-shadow:0 2px 10px rgba(11,13,18,.05);
  transition:border-color .2s var(--ease),box-shadow .2s var(--ease);
}
.home-v4 .h-scan:focus-within{border-color:rgba(124,108,255,.55);box-shadow:0 0 0 4px rgba(124,108,255,.13)}
.home-v4 .h-scan input{
  flex:1;min-width:0;padding:12px 18px;font:inherit;font-size:15.5px;
  color:var(--ink);background:none;border:0;outline:none;
}
.home-v4 .h-scan input::placeholder{color:#98A0B4}
.home-v4 .h-scan input:focus-visible{outline:none}
.home-v4 .h-scan .h-btn{flex:none}
.home-v4 .h-cta-note{
  /* --ink-3 measured 3.7:1 here, under AA for 12.5px text. */
  margin-top:16px;font-size:12.5px;color:#596172;
  display:flex;align-items:center;justify-content:center;gap:8px;
}
.home-v4 .h-cta-note svg{width:14px;height:14px;flex:none}

/* ═══════════════ motion ═══════════════
   Small distances, quick durations. A 20px rise over 700ms reads as the page
   settling; a 60px rise over 1.2s reads as waiting for the page. */

html.js .home-v4 .rv{opacity:0;transform:translateY(14px)}
html.js .home-v4 .rv.in{
  opacity:1;transform:none;
  transition:opacity .6s var(--ease-out),transform .6s var(--ease-out);
}
html.js .home-v4 .rv-s{opacity:0;transform:scale(.985)}
html.js .home-v4 .rv-s.in{
  opacity:1;transform:none;
  transition:opacity .7s var(--ease-out),transform .7s var(--ease-out);
}


/* The typing caret. JS owns the text; CSS owns the cursor. */
.home-v4 .h-sb-a.typing::after{
  content:'';display:inline-block;width:2px;height:1em;margin-left:2px;
  background:var(--violet-3);vertical-align:-.14em;animation:h-caret 1s steps(1) infinite;
}
@keyframes h-caret{50%{opacity:0}}
html.js .home-v4 .h-serp.anim .h-chip{opacity:0;transform:translateY(6px)}
html.js .home-v4 .h-serp.anim .h-chip.in{
  opacity:1;transform:none;transition:opacity .45s var(--ease-out),transform .45s var(--ease-out);
}

@media (prefers-reduced-motion:reduce){
  .home-v4 *,.home-v4 *::before,.home-v4 *::after{
    animation:none!important;transition:none!important;
  }
  .home-v4 .rv,.home-v4 .rv-s{opacity:1!important;transform:none!important}
  .home-v4 .h-serp .h-chip{opacity:1!important;transform:none!important}
  .home-v4 .h-pan{animation:none!important}
  /* Freeze the headline on its completed form rather than on the first
     platform — 'all six of them' is the sentence the rotation exists to
     arrive at, so a reader who never sees motion should get the conclusion. */
  .home-v4 .h-rot-i{opacity:0!important}
  .home-v4 .h-rot-i.fin{opacity:1!important;transform:none!important}
}

/* ═══════════════ responsive ═══════════════ */

/* `1fr` is `minmax(auto,1fr)`, and `auto` floors at the content's min-content
   width — so a grid track will happily grow past the viewport rather than let
   its contents shrink. The app window's indented rows did exactly that on a
   phone. `minmax(0,1fr)` is the fix; body{overflow-x:hidden} only hid it. */
@media (max-width:1080px){
  .home-v4 .h-hero-grid{grid-template-columns:minmax(0,1fr);gap:var(--s-6)}
  .home-v4 .h-hero .lead{max-width:56ch}
  .home-v4 .h-split{grid-template-columns:minmax(0,1fr);gap:var(--s-6)}
  .home-v4 .h-serp-wrap{grid-template-columns:minmax(0,1fr);gap:var(--s-6)}
  .home-v4 .h-flow{grid-template-columns:repeat(3,1fr);row-gap:var(--s-6)}
  .home-v4 .h-flow::before{display:none}
  .home-v4 .h-legend{position:static}
  .home-v4 .h-surf,.home-v4 .h-svc{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:720px){
  .home-v4 .h-hero{padding-top:var(--s-6)}
  .home-v4 h1{font-size:clamp(34px,9vw,46px)}
  .home-v4 .h-pans{min-height:302px}
  /* Six surfaces will not fit one 453px line, and wrapping them leaves a ragged
   4 + 2. A three-column grid makes it a deliberate 3 + 3 instead, with every
   chip the same width, which reads as a set rather than as a row that ran out
   of space. Two columns on a phone for the same reason. */
.home-v4 .h-eng-list{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
.home-v4 .h-eng-i{justify-content:center;min-width:0}
@media (max-width:520px){
  .home-v4 .h-eng-list{grid-template-columns:repeat(2,1fr)}
}
  .home-v4 .h-eng-i{font-size:11px;padding:5px 9px}
  .home-v4 .h-serp{padding:12px}
  .home-v4 .h-sb{padding:12px 12px 12px 36px}
  .home-v4 .h-imgs{grid-template-columns:repeat(3,1fr)}
  .home-v4 .h-vids{grid-template-columns:repeat(2,1fr)}
  .home-v4 .h-surf,.home-v4 .h-svc{grid-template-columns:minmax(0,1fr)}
  .home-v4 .h-btns{width:100%}
  .home-v4 .h-btns .h-btn{flex:1 1 auto;justify-content:center}
  .home-v4 .h-flow{grid-template-columns:repeat(2,1fr);row-gap:var(--s-6)}
  .home-v4 .h-flow::before{display:none}
  .home-v4 .h-scan{flex-direction:column;border-radius:var(--r-lg);padding:10px}
  .home-v4 .h-scan input{text-align:center}
  .home-v4 .h-scan .h-btn{width:100%}
  .home-v4 .h-claim{gap:12px}
}

/* ═══════════════ 8 · proof / testimonials ═══════════════

   A bento, not a uniform 3x2. Five equal cards would have said all five
   engagements weigh the same, and they do not: TeckWrap spans two columns
   because four markets is the biggest claim here, and SEJ is the narrow one
   because a tall card is the shape that fits a search result mock.

   Colour is per card via --ac, set inline in the markup. It touches three
   things only: the quote glyph, the monogram, and the hairline that lights up
   on hover. Any more and five accents in one grid becomes a fruit salad. */

.home-v4 .h-proof{
  background:var(--night);
  border-top:1px solid rgba(255,255,255,.06);
}
/* Depth without a texture file. Two very wide, very faint radials stop the
   black reading as an unstyled background. */
.home-v4 .h-proof::before{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(60% 42% at 18% 0%,rgba(108,92,231,.16),transparent 62%),
    radial-gradient(48% 38% at 88% 8%,rgba(34,193,220,.10),transparent 60%);
}
.home-v4 .h-proof > .wrap{position:relative;z-index:1}
.home-v4 .h-proof .h-head{max-width:720px}
.home-v4 .h-proof .h-head .lead{color:#8F97AB}

.home-v4 .h-tg{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:14px;
  /* Cards in a row share a height. This was briefly align-items:start, to stop
     a thin card being stretched and left holding 156px of nothing above its
     quote and 156px below. That cured the inside of one card and moved the hole
     outside it: at 1280px the second row then ran 791, 282 and 365 tall against
     a flat top edge, leaving 509px and 426px of empty section under the two
     short cards and a staircase along the bottom of the grid. Generous padding
     inside a card reads as setting; a ragged row edge reads as broken markup.
     The height difference is treated at source instead, by compacting the stat
     block in a narrow card and giving a card with no stats larger type. */
}

/* ── the card ── */
.home-v4 .h-t{
  position:relative;display:flex;flex-direction:column;
  gap:var(--s-4);
  padding:clamp(22px,2.2vw,30px);
  border-radius:var(--r-lg);
  background:linear-gradient(180deg,rgba(255,255,255,.055),rgba(255,255,255,.022));
  border:1px solid rgba(255,255,255,.085);
  overflow:hidden;
  transition:transform .3s var(--ease),border-color .3s var(--ease),
             background .3s var(--ease),box-shadow .3s var(--ease);
}
/* The accent hairline along the top edge. Off by default so the grid stays
   calm, drawn in on hover from the left. */
.home-v4 .h-t::after{
  content:'';position:absolute;top:0;left:0;right:0;height:1.5px;
  background:linear-gradient(90deg,var(--ac),transparent 72%);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform .42s var(--ease-out);
}
.home-v4 .h-t:hover{
  transform:translateY(-3px);
  border-color:rgba(255,255,255,.16);
  background:linear-gradient(180deg,rgba(255,255,255,.075),rgba(255,255,255,.03));
  box-shadow:0 22px 50px rgba(0,0,0,.42);
}
.home-v4 .h-t:hover::after{transform:scaleX(1)}

.home-v4 .h-t-wide{grid-column:span 2}

.home-v4 .h-t-q{display:block;color:var(--ac);opacity:.55;line-height:0}
.home-v4 .h-t-q svg{display:block}

.home-v4 .h-t blockquote{margin:0}
.home-v4 .h-t blockquote p{
  color:#DCDFE8;
  font-size:15.5px;line-height:1.62;letter-spacing:-.011em;
  text-wrap:pretty;
}
/* The claim inside the claim. A testimonial is read at a glance or not at all,
   and the sentence that matters is rarely the first one, so the two or three
   phrases carrying the actual result take the card's accent and a little more
   weight. Kept to <strong> rather than a highlighter fill: a tinted background
   behind running text reads as a marketing device, colour alone reads as
   emphasis. Use it twice per quote at most, or it stops meaning anything. */
.home-v4 .h-t blockquote strong{color:var(--ac);font-weight:600}

/* The two feature cards carry the argument, so their quotes get real size.

   The wide one is set as a genuine pull quote rather than body copy. It shares
   a grid row with the tall card, so it is stretched to that card's height, and
   at 21px it under-filled a 737x521 box: MEASURED a 190px hole between the flag
   row and the byline, which reads as a broken card rather than as space. The
   larger type plus a blockquote that takes the slack (flex:1, optically
   centred) absorbs it, and the byline still sits on the bottom edge in line
   with every other card in the grid.

   The same flex:1 is on every card for the same reason one row down:
   TeckWrapCraft carries a chip row the other two do not, so it sets the row
   height and left VinylFrog and KawaiiStories holding 83px and 108px of dead
   space under their quotes. Splitting that slack above and below the quote
   reads as generous setting; dumping all of it in one place read as a bug. */
.home-v4 .h-t blockquote{flex:1;display:flex;align-items:center}
/* Stepped down from 27px: the card gained a brand strip and five stat tiles,
   and a pull quote that size fought all of them for the same attention. At 19px
   it leads the card without swallowing it. */
.home-v4 .h-t-wide blockquote p{font-size:clamp(16.5px,1.55vw,19px);line-height:1.55;letter-spacing:-.016em}
.home-v4 .h-t-tall blockquote p{font-size:16.5px;line-height:1.56;letter-spacing:-.014em}

/* Pushes the attribution to the bottom edge so every card's byline lines up
   across the row regardless of quote length. */
.home-v4 .h-t-by{
  display:flex;align-items:center;gap:11px;
  margin-top:auto;padding-top:var(--s-3);
  border-top:1px solid rgba(255,255,255,.07);
  font-size:13.5px;color:#8B93A7;letter-spacing:-.006em;
}
.home-v4 .h-t-by b{color:#EDEFF5;font-weight:600}

/* A monogram, not a stock face. We do not have photographs of these people and
   a generic avatar would be inventing one. */
.home-v4 .h-t-av{
  flex:none;display:grid;place-items:center;
  width:36px;height:36px;border-radius:11px;
  font-family:'Inter Tight',sans-serif;font-size:15px;font-weight:600;
  letter-spacing:-.02em;
  color:var(--ac);
  background:color-mix(in srgb,var(--ac) 17%,transparent);
  border:1px solid color-mix(in srgb,var(--ac) 30%,transparent);
}

/* ── brand strip + markets (TeckWrap) ──
   Name and flags on one line, separated by a rule that fills whatever space is
   left. The flags sit on the right so the six of them read as one object
   rather than as a tail on the end of the heading. */
.home-v4 .h-t-brand{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding-bottom:var(--s-3);
  border-bottom:1px solid rgba(255,255,255,.07);
}
.home-v4 .h-t-brand h3{
  font-size:clamp(17px,1.5vw,20px);color:#fff;letter-spacing:-.026em;margin:0;
}
.home-v4 .h-t-flags{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-left:auto}
/* The narrow card cannot fit a name and a flag row on one line, and a wrapped
   row that is still pushed right by margin-left:auto lands ragged against the
   left edge of nothing. Stacking is the honest version of the same layout. */
.home-v4 .h-t-brand-stack{flex-direction:column;align-items:flex-start;gap:11px}
.home-v4 .h-t-brand-stack .h-t-flags{margin-left:0}
.home-v4 .h-t-flag{
  display:block;line-height:0;border-radius:4px;overflow:hidden;
  box-shadow:0 0 0 1px rgba(255,255,255,.16),0 2px 6px rgba(0,0,0,.4);
}
.home-v4 .h-t-flag svg{display:block}

/* ── Google Search band (TeckWrap) ──
   Set apart from the social tiles rather than made to match them: these are
   four readings of one channel, where each tile below is one reading of a
   different channel. Grouping them inside a single labelled container is what
   says that. The dividers do the same job the tile borders do downstairs. */
.home-v4 .h-t-gsc{
  display:flex;flex-direction:column;gap:11px;
  padding:13px 15px 14px;border-radius:var(--r-sm);
  background:rgba(255,255,255,.045);
  border:1px solid rgba(255,255,255,.075);
  transition:background .22s var(--ease),border-color .22s var(--ease);
}
.home-v4 .h-t:hover .h-t-gsc{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.11)}
.home-v4 .h-t-gsc-h{
  display:flex;align-items:center;gap:8px;
  font-family:'IBM Plex Mono',monospace;
  font-size:10.5px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;
  color:#9BA2B4;
}
.home-v4 .h-t-gsc-h svg{display:block;flex:none}
/* One figure does not need a row of its own under the label. Set side by side
   the band reads as a single stated fact; stacked, the number sat at the far
   left of a 646px cell with the rest of the row empty behind it. */
.home-v4 .h-t-gsc-solo{flex-direction:row;align-items:center;justify-content:space-between;gap:18px;padding-top:14px}
.home-v4 .h-t-gsc-solo .h-t-gsc-h{margin-bottom:0}
.home-v4 .h-t-gsc-solo .h-t-gsc-g{flex:0 0 auto}
.home-v4 .h-t-gsc-solo .h-t-g{flex:0 0 auto;align-items:flex-end;text-align:right;padding-left:0;border-left:0}
/* The period is the half of this label that makes the numbers mean anything,
   so it is not hidden, only set apart: same size, dimmer, upright. */
.home-v4 .h-t-gsc-h i{font-style:normal;color:#6E7689}
/* Flex, not a fixed four-column grid: not every store hands over the full
   Search Console panel. VinylFrog gave clicks only, and one child in a
   repeat(4,1fr) grid sits in a quarter of the band with three empty columns
   beside it, which reads as data that failed to load. Flex lets one figure
   fill the row and four share it evenly. */
.home-v4 .h-t-gsc-g{display:flex;flex-wrap:wrap;gap:12px}
.home-v4 .h-t-g{
  flex:1 1 0;min-width:74px;
  display:flex;flex-direction:column;gap:3px;
  padding-left:12px;border-left:1px solid rgba(255,255,255,.09);
}
.home-v4 .h-t-g:first-child{padding-left:0;border-left:0}
.home-v4 .h-t-g b{
  font-family:'Inter Tight',sans-serif;
  font-size:clamp(16px,1.5vw,19px);font-weight:650;line-height:1;
  letter-spacing:-.03em;color:#fff;font-variant-numeric:tabular-nums;
}
.home-v4 .h-t-g span{font-size:10.5px;line-height:1.25;color:#8B93A7;letter-spacing:.03em}

/* ── platform numbers (TeckWrap) ──
   Five equal tiles. The number is the thing being read, so it gets the weight
   and tabular figures; the label under it is deliberately small, because
   "Followers" five times is the least interesting text on the card. Pinterest
   says Monthly views instead, which is the metric that platform is judged on
   and the reason the labels are per-tile rather than one heading. */
.home-v4 .h-t-plat{display:grid;grid-template-columns:repeat(5,1fr);gap:8px}

/* THE NARROW BUILD. Five tiles across a 361px column leaves each about 52px,
   narrower than "79.5K" sets at this size. Two across fixed the clipping and
   cost three rows of 84px tiles, which is what made VinylFrog 791px tall and
   wrecked the row it sits in.

   So a narrow card drops the tile entirely and lists the platforms instead:
   one line each, mark on the left, number next to it, metric pushed right. It
   is a third of the height, it scans faster than a grid of boxes, and it reads
   the metric per line, which matters when four say Followers and Pinterest
   says Monthly views. Keyed off the card class, not a viewport width, because
   what decides this is card width, and at 1280px the page shows a 737px card
   and a 361px card at the same time. */
.home-v4 .h-t:not(.h-t-wide) .h-t-plat{display:flex;flex-direction:column;gap:0}
.home-v4 .h-t:not(.h-t-wide) .h-t-p{
  flex-direction:row;align-items:baseline;gap:10px;
  padding:8px 2px;border:0;border-radius:0;background:none;
  box-shadow:inset 0 -1px 0 rgba(255,255,255,.07);
}
.home-v4 .h-t:not(.h-t-wide) .h-t-p:last-child{box-shadow:none}
.home-v4 .h-t:hover:not(.h-t-wide) .h-t-p{background:none}
.home-v4 .h-t:not(.h-t-wide) .h-t-p-ic{align-self:center}
.home-v4 .h-t:not(.h-t-wide) .h-t-p-n{font-size:16px}
.home-v4 .h-t:not(.h-t-wide) .h-t-p-l{margin-left:auto;text-align:right}

/* A card with no figures behind it, sized by three neighbours that have them.
   This was briefly set at display size (26px) because the quote was two short
   sentences and the card was holding 194px of nothing above them; type was the
   only honest way to fill a box that padding could not.

   The quote is now a five-step account of the work and fills the card on its
   own, so the display setting would overshoot in the other direction and make
   this the tallest card in the row. A modest bump over body size is enough. */
.home-v4 .h-t-lite blockquote p{font-size:17px;line-height:1.5;letter-spacing:-.015em;color:#E2E5ED}
.home-v4 .h-t-p{
  display:flex;flex-direction:column;align-items:flex-start;gap:5px;
  padding:12px 12px 13px;border-radius:var(--r-sm);
  background:rgba(255,255,255,.045);
  border:1px solid rgba(255,255,255,.075);
  transition:background .22s var(--ease),border-color .22s var(--ease);
}
.home-v4 .h-t:hover .h-t-p{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.11)}
.home-v4 .h-t-p-ic{line-height:0}
.home-v4 .h-t-p-ic svg{display:block}
.home-v4 .h-t-p-n{
  font-family:'Inter Tight',sans-serif;
  font-size:clamp(17px,1.6vw,21px);font-weight:650;line-height:1;
  letter-spacing:-.03em;color:#fff;font-variant-numeric:tabular-nums;
}
.home-v4 .h-t-p-l{
  font-size:10.5px;line-height:1.25;color:#8B93A7;
  letter-spacing:.03em;
}

/* ── AI Overview mock (SEJ) ── */
.home-v4 .h-t-ao{
  border-radius:var(--r);padding:12px;
  background:rgba(0,0,0,.34);
  border:1px solid rgba(255,255,255,.08);
  display:flex;flex-direction:column;gap:10px;
}
.home-v4 .h-t-ao-q{
  display:flex;align-items:center;gap:8px;
  padding:8px 11px;border-radius:99px;
  background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.07);
  color:#9BA2B4;
}
.home-v4 .h-t-ao-q .mono{font-size:12.5px;color:#E6E8EF;letter-spacing:.01em}
.home-v4 .h-t-ao-b{display:flex;flex-direction:column;gap:7px;padding:2px 2px 0}
.home-v4 .h-t-ao-tag{
  display:inline-flex;align-items:center;gap:6px;align-self:flex-start;
  font-family:'IBM Plex Mono',monospace;
  font-size:10.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ac);
}
/* Skeleton lines: the answer text is not the point, the citation is. */
.home-v4 .h-t-ao-l{
  height:6px;border-radius:99px;
  background:linear-gradient(90deg,rgba(255,255,255,.17),rgba(255,255,255,.06));
}
.home-v4 .h-t-ao-l.s{width:62%}
.home-v4 .h-t-ao-cite{
  align-self:flex-start;margin-top:3px;
  padding:5px 10px;border-radius:99px;
  font-size:12px;font-weight:550;letter-spacing:-.004em;
  color:#08070F;background:var(--ac);
}

/* ── method steps (KawaiiStories) ──
   Same bordered panel as the search band and the headline stat, so every card
   in the grid carries exactly one block and the row has a shared rhythm. What
   goes in the panel differs because what each store has differs; the frame
   staying constant is what stops that reading as five unrelated designs.

   The rule down the left is drawn on the list, not per item, so it runs
   continuously behind the numbers instead of restarting at each one. */
.home-v4 .h-t-steps{
  padding:14px 16px 15px;border-radius:var(--r-sm);
  background:rgba(255,255,255,.045);
  border:1px solid rgba(255,255,255,.075);
  transition:background .22s var(--ease),border-color .22s var(--ease);
}
.home-v4 .h-t:hover .h-t-steps{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.11)}
.home-v4 .h-t-steps-h{
  font-family:'IBM Plex Mono',monospace;
  font-size:10.5px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;
  color:#9BA2B4;margin-bottom:11px;
}
.home-v4 .h-t-steps ol{list-style:none;margin:0;padding:0 0 0 13px;position:relative}
.home-v4 .h-t-steps ol::before{
  content:'';position:absolute;left:0;top:6px;bottom:6px;width:1px;
  background:linear-gradient(180deg,var(--ac),rgba(255,255,255,.10));
  opacity:.55;
}
.home-v4 .h-t-steps li{display:flex;align-items:baseline;gap:10px;padding:5px 0}
.home-v4 .h-t-steps li i{
  font-style:normal;flex:none;
  font-family:'IBM Plex Mono',monospace;
  font-size:10.5px;font-weight:600;letter-spacing:.04em;
  color:var(--ac);font-variant-numeric:tabular-nums;
}
.home-v4 .h-t-steps li span{font-size:13.5px;line-height:1.35;color:#C6CBD8;letter-spacing:-.008em}

/* ── headline stat (TeckWrapCraft) ──
   One number, set at the size the claim deserves. A store that has given a
   single figure should lead with it rather than footnote it, and at this scale
   it also does the job the stat block does on the other cards: it gives the
   card something to hold, instead of a short quote floating in a tall box. */
.home-v4 .h-t-big{
  display:flex;flex-direction:column;gap:9px;
  padding:16px 16px 15px;border-radius:var(--r-sm);
  background:rgba(255,255,255,.045);
  border:1px solid rgba(255,255,255,.075);
  transition:background .22s var(--ease),border-color .22s var(--ease);
}
.home-v4 .h-t:hover .h-t-big{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.11)}
.home-v4 .h-t-big > b{
  font-family:'Inter Tight',sans-serif;
  font-size:clamp(38px,4vw,52px);font-weight:650;line-height:.92;
  letter-spacing:-.045em;color:var(--ac);font-variant-numeric:tabular-nums;
}
.home-v4 .h-t-big > span{font-size:13.5px;line-height:1.45;color:#B6BCCA;letter-spacing:-.008em;text-wrap:pretty}

/* ── responsive ──
   At 2 columns the wide card keeps its span and the narrow ones pair up. At 1
   column every card is the same shape, which is correct: the bento encodes
   emphasis through width, and there is no width left to encode it with. */
@media (max-width:1000px){
  .home-v4 .h-tg{grid-template-columns:repeat(2,1fr)}
  .home-v4 .h-t-wide{grid-column:span 2}
  .home-v4 .h-t-wide blockquote p{font-size:clamp(17px,2.4vw,20px)}
}
/* Five tiles do not divide by two or three, so a naive column count always
   strands the last one in a row of its own. A 6-track grid solves both narrow
   cases: spans of 2 give three per row, and the remaining pair take spans of 3
   to fill the width between them. */
@media (max-width:860px){
  .home-v4 .h-t-plat{grid-template-columns:repeat(6,1fr)}
  .home-v4 .h-t-p{grid-column:span 2}
  .home-v4 .h-t-p:nth-child(4),.home-v4 .h-t-p:nth-child(5){grid-column:span 3}
}
@media (max-width:640px){
  /* The line breaks after the second claim at this width. The separator lives
     inside the following span, so without this the third line would open with
     a dangling middot: the dot is dropped and the claim takes a row of its own
     rather than trailing a mark that separates it from nothing. */
  .home-v4 .label-dots span:nth-child(3){flex-basis:100%;justify-content:center}
  .home-v4 .label-dots span:nth-child(3)::before{display:none}

  .home-v4 .h-tg{grid-template-columns:1fr;gap:12px}
  .home-v4 .h-t-gsc-g{gap:10px 12px}
  .home-v4 .h-t-g{flex:1 1 40%}
  /* Row two starts a new line, so its first cell loses the divider too. */
  .home-v4 .h-t-g:nth-child(odd){padding-left:0;border-left:0}
  .home-v4 .h-t-plat{grid-template-columns:repeat(2,1fr)}
  .home-v4 .h-t-p{grid-column:span 1}
  /* Two per row leaves Pinterest last and alone, so it takes the full width.
     It is also the tile carrying the unusual metric, so the extra room reads
     as emphasis rather than as a leftover. */
  .home-v4 .h-t-p:nth-child(4){grid-column:span 1}
  .home-v4 .h-t-p:nth-child(5){grid-column:span 2}
  .home-v4 .h-t-brand h3{font-size:17px}
  .home-v4 .h-t-flags{margin-left:0}
  .home-v4 .h-t-wide,.home-v4 .h-t-tall{grid-column:span 1}
  .home-v4 .h-t{gap:var(--s-3)}
  .home-v4 .h-t-wide blockquote p{font-size:17.5px;line-height:1.52}
}
