/* Goodie AI Visibility Index editorial pages.
 *
 * Built on parts/components/tool-grid, the hairline grid shared with the
 * free-tool blocks. Two rules from that component carry over here and are easy
 * to undo by accident:
 *
 * 1. Structural panels take no borders. Every rule between panels is the
 *    line-coloured background of a flex/grid parent showing through a 1px gap.
 *    Adding a border paints a second line right beside the gap. Borders remain
 *    only inside leaf components a gap cannot reach — table rows, accordion
 *    items, list rows.
 * 2. Whitespace between panels is painted, never margin. Margin would expose
 *    the parent's line colour as a solid slab. Sections paint their own
 *    trailing space via ::after; standalone bands use a tool-grid__spacer.
 *
 * Content aligns to a single --gdi-gutter rail so headings, rules and cells
 * all start on the same vertical line at any viewport width. */
.gd-index{
  /* The theme's own stack, spelled out. Read through --bs-body-font-family it
     never reached UncutSans: Bootstrap defines that variable as its system
     stack, so the fallback listed after it could not apply and these pages set
     themselves in system-ui while the rest of the site did not. */
  --gdi-font:UncutSans,"Roboto Condensed",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;
  --gdi-mono:AzeretMono,ui-monospace,"Roboto Condensed",SFMono-Regular,monospace;
  --gdi-bg:var(--color-graphite);
  --gdi-line:var(--color-grid-dark);
  --gdi-line-strong:var(--color-grid-light);
  --gdi-text:var(--color-white);
  --gdi-body:var(--color-light-grey);
  --gdi-muted:var(--color-mid-grey);
  --gdi-subtle:var(--color-dark-grey);
  --gdi-blue:var(--color-blue);
  --gdi-green:#00bc7d;
  --gdi-red:#fb2c36;
  --gdi-orange:var(--color-dark-orange);
  --gdi-gutter:24px;
  --gdi-rhythm:112px;
  --gdi-hover:color-mix(in srgb,var(--color-white) 3%,transparent);
  background:var(--gdi-bg);
  color:var(--gdi-text);
  font-family:var(--gdi-font);
  font-size:16px;
  line-height:1.5;
  padding:0 0 var(--gdi-rhythm);
}
.gd-index *{box-sizing:border-box}
/* The theme sets links and buttons in the mono face globally; these pages are
   data-dense, so everything reverts to the sans and opts back into mono.
   .btn is exempt throughout: it is the theme's own button, carried in by the
   Signet block that closes the page, and it is set in mono everywhere else on
   the site. The page's own buttons are .gdi-btn and .gdi-sbtn, so they keep the
   sans as before. */
.gd-index a:not(.btn),.gd-index button:not(.btn),
.gd-index input,.gd-index th,.gd-index td{font-family:var(--gdi-font)}
.gd-index a:not(.btn){color:var(--gdi-blue);text-decoration:none}
.gd-index a:not(.btn):hover{text-decoration:underline}
/* .gdi-wrap carries the component's .tool-grid class, so it is a 1px-gap flex
   column over the line colour. Its children have to be painted or the line
   shows through the whole panel. */
.gdi-wrap{width:100%}
/* Panels that are themselves grids re-assert the line colour further down this
   file, so this stays a plain single-class selector they can outrank by order. */
.gdi-wrap>*,.gdi-sec>*,.gdi-card>*{background:var(--gdi-bg);min-width:0}
.gdi-sec,.gdi-card{display:flex;flex-direction:column;gap:1px;background:var(--gdi-line)}
/* Painted trailing whitespace. As a flex item it also picks up the parent's
   gap, which draws the section's closing rule above it. */
.gdi-sec::after{content:"";display:block;height:var(--gdi-rhythm);background:var(--gdi-bg)}
.gdi-vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.gdi-num{font-variant-numeric:tabular-nums}

/* Breadcrumb trail, one shared array feeding both this and the BreadcrumbList
   JSON-LD (gd_index_breadcrumb_nav_html / gd_index_breadcrumb_schema), so the
   two can never disagree. Sits as a 48px rail child above the hero. Sentence
   case in the page sans: ancestors muted, current in white, chevrons between.
   Link selectors outrank `.gd-index a:not(.btn)` so the trail does not pick
   up the page's default blue. */
.gdi-crumbs{padding:0}
.gdi-crumbs ol{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-height:48px;
  margin:0;padding:0 var(--gdi-gutter);list-style:none
}
.gdi-crumbs__item{
  display:flex;align-items:center;gap:8px;font-size:14px;line-height:1.2;
  color:var(--gdi-muted)
}
.gdi-crumbs__item:not(:last-child)::after{
  content:"";display:block;width:12px;height:12px;flex-shrink:0;background:var(--gdi-subtle);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M4.5 2.5L8 6L4.5 9.5' stroke='black' stroke-width='1.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/12px 12px no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M4.5 2.5L8 6L4.5 9.5' stroke='black' stroke-width='1.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/12px 12px no-repeat
}
.gd-index .gdi-crumbs a:not(.btn){color:var(--gdi-muted)}
.gd-index .gdi-crumbs a:not(.btn):hover{color:var(--gdi-text);text-decoration:none}
.gdi-crumbs [aria-current="page"]{color:var(--gdi-text)}

/* Every band shares one rail, so headings, rules and cells all start on the
   same vertical line no matter how wide the viewport gets. */
.gdi-edition__body,
.gdi-sechead,.gdi-cardhead,.gdi-bcell,.gdi-ecell,.gdi-mcol,.gdi-movecol,
.gdi-prose,.gdi-cardfoot,.gdi-cta,.gdi-gaplist,
.gdi-split__head,.gdi-splitrow,
.gd-index th,.gd-index td{padding-left:var(--gdi-gutter);padding-right:var(--gdi-gutter)}

.gdi-lbl,.gdi-sechead .rt,.gdi-mmeta{
  font-family:var(--gdi-mono);font-size:13px;font-weight:400;line-height:1;
  letter-spacing:.02em;text-transform:uppercase;color:var(--gdi-muted)
}
.gdi-mmeta a,.gd-index .gdi-chip{font-family:var(--gdi-mono)}

/* Hero — the tool-grid composition used by the free-tool pages: a narrow strip
   plus two stacked cells on each flank, and a centred copy column. The flank
   panels come from the component; only the copy column is this page's own. */
.gdi-hero{text-align:center;background:var(--gdi-line)}
.gdi-hero__content{
  position:relative;min-height:400px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;
  padding:0 48px;
  /* So .gdi-lockup can size its type against the space this column actually
     has, rather than against the viewport the column is only a part of. */
  container-type:inline-size
}
.gdi-hero__eyebrow{margin:0;font-family:var(--gdi-mono);font-size:13px;font-weight:400;line-height:1;text-transform:uppercase;color:var(--gdi-blue)}
/* The theme uppercases every unclassed h1; this hero follows the sentence-case
   treatment the sibling hero block uses. */
.gdi-hero__title{max-width:min(660px,100%);margin:0;font-size:clamp(2rem,4vw,2.75rem);font-weight:600;line-height:1.1;letter-spacing:-.02em;color:var(--gdi-text);text-transform:none!important}
.gdi-hero__title .hl{color:var(--gdi-blue)}
/* Opt-in, because most .hl accents sit mid-sentence ("How the Index is built")
   where a break would be wrong. Titles that close on the product name take it so
   the name gets its own line instead of wrapping after its first word. */
.gdi-hero__title .hl-row{display:block}
/* Profile heroes name an entity, so the title is the name alone and the page
   type follows as a label. Given a title line of its own it reads as a second
   headline and competes with the name for the eye. */
.gdi-hero__subtitle{
  margin:0;font-family:var(--gdi-mono);font-size:14px;font-weight:400;line-height:1;
  letter-spacing:.06em;text-transform:uppercase;color:var(--gdi-blue)
}
/* A mark and an entity's name as one title line. A hostname has no break that
   reads well — split at a dot or a hyphen it looks like two different addresses
   — so the line never wraps and gives up size instead. --gdi-lockup-fit is how
   many ems wide the line is, counted by the template where the name is known;
   dividing the column by it shrinks the type for a long name and for a narrow
   screen in the same step, so neither needs its own breakpoint. The floor is a
   readability limit, not a fitting one. */
.gdi-lockup{
  display:flex;align-items:center;justify-content:center;gap:.35em;max-width:100%;
  font-size:clamp(1rem,calc(100cqw / var(--gdi-lockup-fit,12)),2.75rem)
}
/* Past the floor the type can no longer shrink to fit, and a hostname that
   cannot wrap would push the page sideways instead — CDN hosts run to 70-odd
   characters. Truncating is the lesser loss, and the full host is on the page
   twice over in the snapshot below. The name is the page's own <h1> here (a
   heading should hold only text, so the mark beside it rides in the row
   instead — see .gdi-hero__title-row below), which is why this targets that
   heading rather than a span of its own: it needs the row's font-size, not
   its own clamp, and the row's max-width, not the hero title's normal one. */
.gdi-lockup .gdi-hero__title{font-size:inherit;max-width:none;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The mark is the entity's, not the 20px row icon the tables use: sized in em so
   it tracks the name beside it, and wearing the same hairline tile as the badge
   below. */
.gdi-lockup .gdi-favicon{
  width:1em;height:1em;margin:0;padding:.18em;
  border:1px solid var(--gdi-line);border-radius:0
}
.gdi-hero__description{max-width:600px;margin:0;font-size:16px;line-height:1.5;color:var(--gdi-body)}
.gdi-hero__badge{
  position:absolute;bottom:-24px;left:50%;transform:translateX(-50%);z-index:1;
  display:inline-flex;align-items:center;gap:8px;height:48px;padding:16px 24px;
  border:1px solid var(--gdi-line);background:var(--gdi-bg);
  font-family:var(--gdi-mono);font-size:13px;line-height:1;text-transform:uppercase;white-space:nowrap
}
.gdi-hero__badge .d{width:7px;height:7px;flex-shrink:0;border-radius:50%}
.gdi-hero__badge--muted .d{background:var(--gdi-subtle)}
.gdi-hero__badge--warning .d{background:var(--gdi-orange)}
.gdi-hero__badge-label{color:var(--gdi-muted);font-weight:400}
.gdi-hero__badge-value{color:var(--gdi-text);font-weight:400}

/* Hub hero — the same centred composition as the pages above, with the empty
   flanks replaced by the model field on both sides so the two halves match.
   The coverage figures cannot live in a flank without breaking that symmetry,
   so they take a band of their own below (.gdi-hero__band). */
.gdi-hero__band{display:flex;gap:1px;background:var(--gdi-line)}
/* The band's first label is the leftmost text on the page here, so the cells
   take the shared rail rather than the wider padding the old flank used. */
.gdi-hero__band .gdi-hero__stat{flex:1 1 0;min-width:0;padding:0 var(--gdi-gutter)}
/* The badge would otherwise overhang the rule it shares with the band. */
.gdi-hero--hub .gdi-hero__badge{position:static;transform:none;align-self:center;margin-top:8px}
.gdi-hero__mosaic{
  flex:1 1 0;min-width:0;display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(5,1fr);
  gap:1px;background:var(--gdi-line)
}
.gdi-hero__mosaic-cell{display:flex;align-items:center;justify-content:center;min-width:0;min-height:0;background:var(--gdi-bg)}
.gdi-hero__mosaic-cell i,.gdi-hero__mosaic-mark{
  display:flex;align-items:center;justify-content:center;width:42px;height:42px;border-radius:50%;
  border:1px solid color-mix(in srgb,var(--gdi-text) 9%,transparent)
}
.gdi-hero__mosaic-cell i.is-filled{border:0;background:var(--gdi-line)}
.gdi-hero__mosaic-mark{border:0;overflow:hidden}
.gdi-hero__mosaic-mark img{width:100%;height:100%;object-fit:cover}
.gdi-hero__stat{
  flex:1 1 0;display:flex;align-items:center;justify-content:space-between;gap:16px;
  min-height:96px;padding:0 32px;background:var(--gdi-bg)
}
.gdi-hero__stat-label{font-family:var(--gdi-mono);font-size:12px;letter-spacing:.02em;text-transform:uppercase;color:var(--gdi-muted)}
.gdi-hero__stat-value{font-size:28px;font-weight:500;line-height:1;letter-spacing:-.03em;color:var(--gdi-text);font-variant-numeric:tabular-nums}
.gdi-enginerow{display:inline-flex;align-items:center;gap:8px}
.gdi-model-label{display:inline-flex;align-items:center;gap:6px;color:var(--gdi-text)}
.gdi-model-label .gdi-engine-icon{width:16px;height:16px}
.gdi-hero__stat .gdi-engine-icon{width:28px;height:28px}

/* The industry hero's badge overhangs 24px into the band below it, which is why
   .gdi-edition__body carries 56px of top padding. The hub puts its figures band
   in between instead, and nothing overhangs that, so the clearance comes back
   off there. (This replaced .gdi-capsule, which the hub used to carry.) */
.gdi-hero__band+.gdi-edition .gdi-edition__body{padding-top:40px}

/* Edition summary — the industry page's opening band. A single centred column
   of copy: the leading brand's name and score are already the first thing the
   paragraph says and the first row of the leaderboard, so a figure cell
   restating them earned no width.
   Composed as a tool-grid row — painted gutter, copy, painted gutter — so the
   rules either side are the band's line colour showing through the 1px gaps,
   the same mechanism as every other rule on the page. They run the full height
   of the band and meet the rules above and below, which are themselves the gaps
   between bands in .gdi-wrap. The column takes the hero's own 704px measure, so
   this pair of rules continues the hero's straight down the page rather than
   opening a second set at a new position. Below 1024px the component drops the
   gutters and the band goes full width on its own.
   As a direct child of .gdi-wrap it has to re-assert the line colour to outrank
   that rule's flat --gdi-bg, which is what the gaps show through. */
.gdi-edition{display:flex;gap:1px;background:var(--gdi-line)}
/* No flex or width here: the tool-grid content class on the same element sets
   both, and this stylesheet loads after the component, so anything set here
   would silently win and collapse the column.
   56/40 rather than an even 32: the centred hero's badge is absolute and hangs
   24px down over the rule into this band, so the first line has to clear it.
   Same clearance the capsule this replaced carried. */
.gdi-edition__body{
  min-width:0;display:flex;flex-direction:column;justify-content:center;
  padding-top:56px;padding-bottom:40px;background:var(--gdi-bg);
  font-size:19px;line-height:1.6;color:var(--gdi-body)
}
.gdi-edition__body p{margin:0}
.gdi-edition b{color:var(--gdi-text);font-weight:600}
.gdi-edition .cite{
  display:block;margin-top:20px;font-family:var(--gdi-mono);font-size:13px;line-height:1.6;
  text-transform:uppercase;color:var(--gdi-subtle)
}

/* Engine and view tabs. Pills carrying the theme button's outline treatment:
   transparent while unselected, with the same bottom-up orange reveal on hover.
   Every selector is prefixed with .gd-index so it outranks the .gd-index a
   colour and hover underline set at the top of this file.
   The reveal sits on ::after in the negative layer of an isolated stacking
   context: the label is a bare text node, so there is nothing to lift above a
   pseudo element painted in the positive layer the way .btn does it. */
.gd-index .gdi-sbtn{
  position:relative;isolation:isolate;overflow:hidden;
  display:inline-flex;align-items:center;justify-content:center;gap:8px;height:36px;
  padding:0 20px;border:1px solid var(--gdi-text);border-radius:360px;background:transparent;
  color:var(--gdi-text);font-family:var(--gdi-font);font-size:16px;line-height:1;cursor:pointer;
  transition:border-color .3s cubic-bezier(.4,0,.2,1),color .3s cubic-bezier(.4,0,.2,1)
}
.gd-index .gdi-sbtn .gdi-engine-icon,
.gd-index .gdi-sbtn .gdi-sbtn__mark{display:block;flex-shrink:0}
.gd-index .gdi-sbtn .gdi-sbtn__mark svg{display:block}
.gd-index .gdi-sbtn .gdi-sbtn__label{line-height:1}
.gd-index .gdi-sbtn::after{
  content:"";position:absolute;right:0;bottom:0;left:0;height:0;z-index:-1;
  background:
    linear-gradient(180deg,color-mix(in srgb,var(--color-light-orange) 0%,transparent) 0%,color-mix(in srgb,var(--color-light-orange) 25%,transparent) 100%),
    var(--color-dark-orange);
  transition:height .3s cubic-bezier(.4,0,.2,1)
}
.gd-index .gdi-sbtn:hover,.gd-index .gdi-sbtn:focus-visible{
  border-color:var(--color-light-orange);color:var(--color-black);text-decoration:none
}
.gd-index .gdi-sbtn:hover::after,.gd-index .gdi-sbtn:focus-visible::after{height:100%}
/* The selected filter reads as the page's primary button. It keeps its fill on
   hover — it points at the view you are already looking at. */
.gd-index .gdi-sbtn.on{border-color:var(--gdi-blue);background:var(--gdi-blue);color:var(--color-black)}
.gd-index .gdi-sbtn.on::after{content:none}
/* ─── Skeleton: engine cut in flight ─────────────────────────────────── */
/* JS puts .is-swapping on .gdi-wrap a beat into the fetch, never immediately,
   so a warm cache answers without the skeleton ever showing.
   Each data-bearing element keeps its own box and hides its contents behind a
   shimmer bar rather than the page collapsing to a placeholder layout: the
   rails, row heights and column widths are already correct, so nothing shifts
   when the real markup lands. The pills stay lit and clickable throughout —
   they are the control, and a second click just supersedes the first.
   :where() keeps every selector below at the specificity of .gdi-wrap.is-swapping
   alone, so these read in source order and outrank the .gd-index td colours. */
.gdi-wrap.is-swapping :where(tbody td,.gdi-hero__stat-value,
.gdi-moverow__id,.gdi-moverow__d,.gdi-mrow b,.gdi-mrow .v,.gdi-mix__bar){position:relative;color:transparent}
/* .bv/.ev carry real specificity here, not :where()'s flattened kind, and for
   the same reason the small rule right after this one does: their own base
   colour (color:var(--gdi-text)) sits later in this file and ties with
   :where()'s specificity, so on that tie the later rule used to win — the
   shimmer bar sat on top of a number that was never actually made transparent,
   which is what let its outer edges show past the bar underneath it. */
.gdi-wrap.is-swapping .gdi-bcell .bv,.gdi-wrap.is-swapping .gdi-ecell .ev{position:relative;color:transparent}
/* The unit suffix (%, /100) carries its own explicit colour too, which the
   same tie would otherwise let win over .bv/.ev going transparent above. */
.gdi-wrap.is-swapping .gdi-bcell .bv small,.gdi-wrap.is-swapping .gdi-ecell .ev small{color:transparent}
/* Bars, favicons, progress tracks and links are elements, not text, so
   transparent colour alone would leave them painted over the shimmer. */
.gdi-wrap.is-swapping :where(tbody td,.gdi-moverow__id,.gdi-mrow b,.gdi-mix__bar)>*{visibility:hidden}
/* The key states the same figures as the bar in text, so it goes with it
   rather than sitting under a shimmer quoting the previous cut's numbers. */
.gdi-wrap.is-swapping .gdi-mix__key{visibility:hidden}
.gdi-wrap.is-swapping :where(tbody td,.gdi-bcell .bv,.gdi-ecell .ev,.gdi-hero__stat-value,
.gdi-moverow__id,.gdi-moverow__d,.gdi-mrow b,.gdi-mrow .v,.gdi-mix__bar)::after{
  content:"";position:absolute;top:50%;left:0;right:0;transform:translateY(-50%);
  height:var(--gdi-skel-h,12px);max-width:var(--gdi-skel-w,100%);border-radius:360px;
  background:linear-gradient(90deg,var(--gdi-line) 25%,color-mix(in srgb,var(--color-white) 8%,var(--gdi-line)) 50%,var(--gdi-line) 75%);
  background-size:200% 100%;animation:gdi-skeleton 1.4s linear infinite
}
/* Table cells inset to the rail so the bars start where the type they stand in
   for starts, rather than under the cell's padding. */
.gdi-wrap.is-swapping tbody td::after{left:var(--gdi-gutter);right:var(--gdi-gutter)}
/* Bars sized to the column they replace, so the skeleton reads as a table of
   ranks, names and figures instead of a stack of identical slabs. */
.gdi-wrap.is-swapping :where(td.gdi-rank){--gdi-skel-w:20px}
.gdi-wrap.is-swapping :where(td.gdi-num,td.gdi-muted,.gdi-moverow__d,.gdi-mrow .v){--gdi-skel-w:56px}
.gdi-wrap.is-swapping :where(.gdi-bcell .bv,.gdi-ecell .ev){--gdi-skel-h:24px;--gdi-skel-w:112px}
.gdi-wrap.is-swapping :where(.gdi-mix__bar){--gdi-skel-h:44px}
.gdi-wrap.is-swapping :where(.gdi-hero__stat-value){--gdi-skel-h:16px;--gdi-skel-w:120px}
.gdi-wrap.is-swapping :where(.gdi-moverow__id){--gdi-skel-w:70%}
/* Nothing under the skeleton is real yet, so it takes no hover and no clicks. */
.gdi-wrap.is-swapping tbody{pointer-events:none}
.gdi-wrap.is-swapping tbody tr:hover{background:transparent}
@keyframes gdi-skeleton{from{background-position:150% 0}to{background-position:-150% 0}}
@media(prefers-reduced-motion:reduce){
  .gdi-wrap.is-swapping :where(tbody td,.gdi-bcell .bv,.gdi-ecell .ev,.gdi-hero__stat-value,
  .gdi-moverow__id,.gdi-moverow__d,.gdi-mrow b,.gdi-mrow .v,.gdi-mix__bar)::after{animation:none;background:var(--gdi-line)}
}

/* ─── Row + panel system ─────────────────────────────────────────────── */
.gdi-sechead{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  min-height:80px;padding-top:16px;padding-bottom:16px
}
.gdi-sechead h2{margin:0;font-size:24px;font-weight:600;line-height:1;letter-spacing:-.48px;color:var(--gdi-text)}
.gdi-sechead .note{max-width:600px;font-size:16px;line-height:1.5;color:var(--gdi-muted)}
.gdi-sechead .rt{flex-shrink:0}
.gdi-secnote{padding:16px var(--gdi-gutter);font-size:16px;line-height:1.5;color:var(--gdi-muted)}
.gdi-secnote em{font-style:normal;color:var(--gdi-subtle)}
.gdi-cardhead{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  min-height:80px;padding-top:16px;padding-bottom:16px
}
.gdi-cardhead h3,.gdi-cardhead h2{margin:0;font-size:19px;font-weight:600;line-height:1.2;letter-spacing:-.38px;color:var(--gdi-text)}
/* Ride in the right slot of the section header rather than owning a band. */
.gdi-sectools{display:flex;align-items:center;gap:12px;flex:0 1 600px;min-width:0}
.gdi-filterbar{display:flex;align-items:center;flex:1 1 auto;min-width:0}
.gdi-filterbar .gdi-search{width:100%;max-width:none}

/* Cell grids: the 1px gap over a line-coloured background draws every
   interior rule, so cells themselves stay borderless. */
.gdi-bench,
.gdi-eviden,.gdi-mgrid,.gdi-tworow{gap:1px;background:var(--gdi-line)}
.gdi-eviden{display:grid;grid-template-columns:repeat(4,1fr)}
.gdi-eviden--three{grid-template-columns:repeat(3,1fr)}
.gdi-eviden--two{grid-template-columns:repeat(2,1fr)}
.gdi-bcell,.gdi-ecell{min-width:0;padding-top:24px;padding-bottom:24px;background:var(--gdi-bg)}
.gdi-bcell .bv,.gdi-ecell .ev{margin-top:16px;font-size:40px;font-weight:500;line-height:1;letter-spacing:-.03em;color:var(--gdi-text)}
.gdi-bcell .bv small,.gdi-ecell .ev small{font-size:16px;font-weight:400;color:var(--gdi-muted)}
/* Needs to outrank `.gdi-ecell .ev` for stat cells holding text, not a figure —
   including the smaller size that rule takes at the stacking breakpoint, which
   is further down the file at the same specificity. Matching the modifier on the
   .ev itself rather than beside it is what wins there. */
.gdi-ecell .ev.gdi-ecell__text{font-size:19px;line-height:1.3;letter-spacing:-.38px;overflow-wrap:anywhere}
/* A URL is one long token with no break that reads well — split at its hyphen it
   looks like two different addresses — so it holds a single line and gives up
   size instead. A handful of brands are stored with hostnames past 45
   characters, which no cell width here fits; those trail off, and the address is
   still complete in the href. */
.gdi-ecell .ev.gdi-ecell__url{
  font-size:16px;letter-spacing:-.32px;overflow-wrap:normal;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis
}
.gdi-bcell .bd,.gdi-ecell .es{margin-top:12px;font-size:16px;line-height:1.4;color:var(--gdi-muted)}
.gdi-bcell .bd b{color:var(--gdi-body);font-weight:400}

/* Benchmarks: six cells on one 3×2 grid, so every cell is the same width and
   every label and figure lands on the same line as its neighbours. Equal rows
   rather than content-sized ones, so the two bands match in height too. */
.gdi-bench{display:grid;grid-template-columns:repeat(3,1fr);grid-auto-rows:1fr}
.gdi-bench .gdi-bcell{display:flex;flex-direction:column}
/* The prose absorbs the cell's slack, which drops the comparison line that
   follows it onto the floor of every cell — the band then closes on one line
   instead of six ragged ones. It stays a plain block: as a flex container it
   would promote the inline <b> figures inside the copy to flex items and break
   each of them onto its own line. */
.gdi-bench .bd{flex:1 1 auto}
/* The index-wide comparison is what makes a figure readable as high or low, so
   it sits on its own line rather than trailing the prose. */
.gdi-bench__vs{
  display:block;margin-top:10px;font-family:var(--gdi-mono);font-size:12px;
  letter-spacing:.02em;text-transform:uppercase;color:var(--gdi-subtle)
}
/* Marks a figure the index cannot measure yet, wherever one appears: a cell
   label, a stat caption or a column heading. */
.gd-index .gdi-lbl em,.gd-index th em{font-style:normal;color:var(--gdi-orange)}
.gdi-info{display:inline-flex;margin-left:6px;vertical-align:-3px;color:var(--gdi-subtle);cursor:help}
.gdi-info:hover,.gdi-info:focus-visible{color:var(--gdi-body)}

/* Citation mix: the one benchmark that is a composition rather than a figure,
   so the cell draws a bar where its neighbours print a number. Segment widths
   are whole percentages already reconciled to 100 in PHP, which lets the bar
   close on its own without a flex-grow filling the remainder. */
.gdi-mix{margin-top:16px}
.gdi-mix__bar{display:flex;height:44px;border-radius:8px;overflow:hidden;background:var(--gdi-line)}
.gdi-mix__seg{
  display:flex;align-items:center;justify-content:center;min-width:0;overflow:hidden;
  font-size:15px;font-weight:500;line-height:1;white-space:nowrap;
  /* The palette is a set of light pastels, so segment labels invert to the
     page background rather than staying in the body colour. */
  color:var(--gdi-bg)
}
.gdi-mix__key{
  display:flex;flex-wrap:wrap;gap:10px 20px;margin:16px 0 0;padding:0;
  list-style:none;font-size:15px;color:var(--gdi-body)
}
.gdi-mix__keyitem{display:flex;align-items:center;gap:8px}
.gdi-mix__dot{width:12px;height:12px;flex:0 0 auto;border-radius:3px}
/* ─── Tables ─────────────────────────────────────────────────────────── */
.gdi-table-wrap{width:100%;overflow-x:auto}
.gd-index table{width:100%;border-collapse:collapse;font-size:16px}
.gd-index th{
  height:64px;padding-top:16px;padding-bottom:16px;border-bottom:1px solid var(--gdi-line);
  color:var(--gdi-muted);font-size:16px;font-weight:400;line-height:1.2;text-align:left;white-space:nowrap
}
.gd-index th.r,.gd-index td.r{text-align:right}
.gd-index td{height:64px;padding-top:16px;padding-bottom:16px;border-bottom:1px solid var(--gdi-line);vertical-align:middle;line-height:1.2}
/* Cell contents are data, never emphasis, so nothing in a table reads as bold. */
.gd-index td b,.gd-index td strong{font-weight:400}
.gd-index tbody tr:last-child td{border-bottom:0}
.gd-index tbody tr:hover{background:var(--gdi-hover)}
.gdi-clickrow{cursor:pointer}
.gdi-leaderboard{min-width:1240px}
.gdi-leaderboard th,.gdi-leaderboard td{padding-left:12px;padding-right:12px}
.gdi-leaderboard th:first-child,.gdi-leaderboard td:first-child{padding-left:var(--gdi-gutter)}
.gdi-leaderboard th:last-child,.gdi-leaderboard td:last-child{padding-right:var(--gdi-gutter)}
.gdi-leaderboard .gdi-enginerow{gap:6px}
.gdi-leaderboard .gdi-engine-icon{width:20px;height:20px}
.gdi-enginecell,.gdi-sourcecell{white-space:nowrap}
.gdi-rank{width:56px;color:var(--gdi-muted)}
.gdi-rbar{display:inline-block;width:3px;height:16px;border-radius:360px;margin-right:16px;vertical-align:middle}
.gdi-palette-1{background:#a5c8ff}.gdi-palette-2{background:#4ade80}.gdi-palette-3{background:#f97316}
.gdi-palette-4{background:#a78bfa}.gdi-palette-5{background:#2dd4bf}.gdi-palette-6{background:#f87171}
.gdi-palette-7{background:#fbbf24}.gdi-palette-8{background:#60a5fa}.gdi-palette-9{background:#f472b6}
.gdi-palette-10{background:#34d399}
.gdi-ent{color:var(--gdi-text)!important}
.gdi-ent:hover{color:var(--gdi-blue)!important;text-decoration:none!important}
/* The whole row is the link, so the name answers to the whole row rather than
   waiting for the pointer to find it. A row's aside link goes somewhere the row
   does not, and stays quiet so it never claims to be what the row will open. */
.gdi-clickrow:hover .gdi-ent:not(.gdi-ent--aside){color:var(--gdi-blue)!important}
.gdi-favicon,.gdi-engine-icon,.gdi-flag{width:20px;height:20px;border-radius:50%;object-fit:cover;flex-shrink:0}
/* A mark sits on the same optical centre as the name beside it whatever size
   either is, which a fixed baseline offset only manages for one pairing. */
.gdi-favicon{margin-right:12px;vertical-align:middle;object-fit:contain}
.gdi-flag{margin-right:12px;vertical-align:middle}
/* Sized, spaced and clipped exactly like .gdi-favicon above: a brand's mark and a
   cited domain's mark sit in the same tables, so a difference between them would
   read as a difference in kind. The initials underneath are the fallback for a
   brand with no site on file, and are covered whole by the image otherwise. */
.gdi-brandmark{
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:var(--gdi-brandmark-size,20px);height:var(--gdi-brandmark-size,20px);
  flex:0 0 var(--gdi-brandmark-size,20px);margin-right:12px;vertical-align:middle;
  overflow:hidden;border-radius:50%;background:var(--gdi-line)
}
/* The initials carry the type rather than the mark itself. A mark sized in em of
   the line it sits on has to keep that line's font-size for its own box to
   measure against, so the shrinking happens one level in. */
.gdi-brandmark>span{
  font-family:var(--gdi-mono);font-size:calc(var(--gdi-brandmark-size,20px) * .38);
  line-height:1;color:var(--gdi-muted)
}
.gdi-brandmark img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;background:var(--gdi-bg)}
/* A mark beside a hero title (a brand's favicon, a domain's) — see the
   $title_icon param on gd_index_hero_html(). The mark sits outside the <h1>
   itself (a heading should hold only text, not an embedded image), as this
   row's sibling instead, which is what keeps the two sharing one centre at
   any type size; the gap replaces the fixed 12px a table row leaves after its
   icon. The name is an anonymous flex item, which is still a block container,
   so a long one wraps inside itself instead of pushing the mark off the line. */
/* .gdi-brandmark's own size is set in em (see gd_index_brand_favicon_html())
   expecting to inherit a hero title's font-size the way it used to sit inside
   the <h1> and pick that up for free. Now that the mark is the heading's
   sibling instead, the row needs to carry that same font-size itself, or the
   mark inherits whatever far smaller size cascades from the page body
   instead. Excludes .gdi-lockup, which sets its own hostname-length-based
   font-size below and must win over this instead of tying with it. */
.gdi-hero__title-row:not(.gdi-lockup){font-size:clamp(2rem,4vw,2.75rem)}
.gdi-hero__title-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;column-gap:.26em}
.gdi-hero__title-row>.gdi-brandmark{margin-right:0}
.gdi-trackwrap{display:flex;align-items:center;gap:12px}
.gdi-track{display:block;width:96px;height:4px;flex-shrink:0;border:0;border-radius:360px;overflow:hidden;background:var(--gdi-line);appearance:none;-webkit-appearance:none}
.gdi-track::-webkit-progress-bar{border-radius:360px;background:var(--gdi-line)}
.gdi-track::-webkit-progress-value{border-radius:360px;background:var(--gdi-blue)}
.gdi-track::-moz-progress-bar{border-radius:360px;background:var(--gdi-blue)}
.gdi-up{color:var(--gdi-green)}.gdi-dn{color:var(--gdi-red)}.gdi-fl,.gdi-muted{color:var(--gdi-muted)}
.gdi-chip{
  display:inline-flex;align-items:center;height:28px;padding:0 8px;border-radius:2px;
  background:var(--gdi-line);font-family:var(--gdi-mono);font-size:11px;line-height:1;
  white-space:nowrap;text-transform:uppercase;color:var(--gdi-muted)
}
.gdi-c-live{color:var(--gdi-green)}
.gdi-c-prev{color:var(--gdi-orange)}
.gdi-c-gate{color:var(--gdi-muted)}
.gdi-c-ed{color:var(--gdi-blue)}
.gdi-c-ugc{color:var(--gdi-muted)}
.gdi-cardfoot{
  display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:64px;
  padding-top:16px;padding-bottom:16px;font-size:16px;color:var(--gdi-muted)
}
.gd-index td.gdi-empty,.gdi-empty{padding-top:40px;padding-bottom:40px;height:auto;text-align:center;color:var(--gdi-muted)}

/* Seven columns can't each carry the full page gutter as padding — that alone
   eats 560px and forces the industry names to wrap. Only the outer cells keep
   the gutter, so the rail still lines up with every other band. */
.gdi-hubtable{min-width:1180px}
.gdi-hubtable th,.gdi-hubtable td{padding-left:16px;padding-right:16px}
.gdi-hubtable th:first-child,.gdi-hubtable td:first-child{padding-left:var(--gdi-gutter)}
.gdi-hubtable th:last-child,.gdi-hubtable td:last-child{padding-right:var(--gdi-gutter)}
/* The chip and figure columns hug their content so the gap either side of them
   stays the 32px every other column gets; all remaining width goes to the three
   variable-length text columns instead of padding out the numbers. */
.gdi-hubtable th:nth-child(2),.gdi-hubtable td:nth-child(2),
.gdi-hubtable th:nth-child(4),.gdi-hubtable td:nth-child(4),
.gdi-hubtable th:nth-child(6),.gdi-hubtable td:nth-child(6),
.gdi-hubtable th:nth-child(7),.gdi-hubtable td:nth-child(7){width:1%;white-space:nowrap}
.gdi-hubtable th:nth-child(1),.gdi-hubtable td:nth-child(1){min-width:260px}
.gdi-hubtable th:nth-child(3),.gdi-hubtable td:nth-child(3){min-width:180px}
.gdi-hubtable th:nth-child(5),.gdi-hubtable td:nth-child(5){min-width:220px;overflow-wrap:anywhere}

/* ─── Controls ───────────────────────────────────────────────────────── */
.gdi-search{
  width:100%;max-width:448px;height:48px;padding:0 16px;border:1px solid var(--gdi-line);
  border-radius:2px;background:var(--gdi-line);color:var(--gdi-text);font:16px/1.2 var(--gdi-font)
}
.gdi-search::placeholder{color:var(--gdi-muted)}
.gdi-search:focus{outline:2px solid var(--gdi-blue);outline-offset:2px}
/* 8px, not the 2px the square controls used: outlined pills need daylight
   between them or the adjacent borders read as one segmented control. */
.gdi-sorter{display:flex;flex-wrap:wrap;gap:8px;transition:opacity .15s ease}
/* The 2×2 mark stands in for "All models" when the pill collapses to an icon
   on a phone. Desktop already has the words, so the mark stays out of the way. */
.gdi-sbtn__mark{display:none}
.gdi-viewtoggle{display:flex;flex-shrink:0;gap:1px;background:var(--gdi-line)}
/* Set in the site's own face at reading size rather than as a mono label: these
   are two views to choose between, not a caption, and the extra weight of real
   type is what makes the filled one read as chosen. */
.gdi-viewtoggle button{
  height:48px;padding:0 24px;border:0;background:var(--gdi-bg);color:var(--gdi-muted);
  font-family:var(--gdi-font);font-size:16px;font-weight:400;line-height:1.2;cursor:pointer
}
.gdi-viewtoggle button:hover{color:var(--gdi-text)}
.gd-index .gdi-viewtoggle button.on{background:var(--gdi-line);color:var(--gdi-text)}
.gdi-viewtoggle button:focus-visible{outline:2px solid var(--gdi-blue);outline-offset:-2px}

/* ─── Industry card view ─────────────────────────────────────────────── */
.gdi-indgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--gdi-line)}
.gdi-indcard{min-width:0;padding:24px var(--gdi-gutter);background:var(--gdi-bg)}
/* Cards rarely divide evenly into the columns, and any cell no card covers
   leaves the grid's line colour showing as a solid block. These fillers pad the
   final row out; how many are needed changes with the column count, so each one
   is tagged with the breakpoints it applies to and hidden elsewhere. */
.gdi-indfill{display:none;background:var(--gdi-bg)}
@media(min-width:1101px){.gdi-indfill.is-3col{display:block}}
@media(min-width:768px) and (max-width:1100px){.gdi-indfill.is-2col{display:block}}
.gdi-indcard__head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}
.gdi-indcard__head .gdi-ent{font-size:19px;font-weight:600;line-height:1.2;letter-spacing:-.38px}
.gdi-indcard .ir{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  min-height:40px;padding:8px 0;border-top:1px solid var(--gdi-line);
  font-size:14px;color:var(--gdi-muted)
}
.gdi-indcard .ir b{min-width:0;color:var(--gdi-text);font-weight:400;text-align:right;overflow-wrap:anywhere}

/* ─── Engine comparison + paired panels ──────────────────────────────── */
.gdi-mgrid{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(240px,1fr);overflow-x:auto}
.gdi-mcol{min-width:0;padding-top:24px;padding-bottom:24px;background:var(--gdi-bg)}
.gdi-mhead{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.gdi-mhead b{font-size:19px;font-weight:600;line-height:1.2;letter-spacing:-.38px}
.gdi-mmeta{margin-bottom:16px}
/* The trailing "full cut" link closes the column, so it takes its spacing from
   the rule above and leaves the column's own padding to close the gap beneath.
   Sharing the lead-in margin alone sat it hard against the last row with all
   the air below it. */
.gdi-mcol>.gdi-mmeta:last-child{margin-top:16px;margin-bottom:0}
.gdi-mmeta a{color:var(--gdi-blue)}
.gdi-mrow{
  display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:48px;
  padding:12px 0;border-bottom:1px solid var(--gdi-line);color:var(--gdi-muted)
}
/* The last row keeps its rule: what follows is a link out, not another brand,
   so the line closes the ranking rather than dividing two rows. */
.gdi-mrow b{display:flex;align-items:center;color:var(--gdi-text);font-weight:400}
/* The rank leads the line here instead of sitting in its own column, so the mark
   needs the space a cell's padding would otherwise have given it. */
.gdi-mrow .gdi-brandmark{margin-left:8px}
.gdi-tworow{display:grid;grid-template-columns:repeat(2,1fr)}
.gdi-tworow--single{grid-template-columns:1fr}

/* Global search demand carries the production Index's map and country list —
   same two panels, same country colours — drawn with this page's gap grid
   rather than the block's borders. The map panel takes about two thirds, which
   is the split the block uses. */
.gdi-market-grid{display:grid;grid-template-columns:minmax(0,1.9fr) minmax(340px,1fr);gap:1px;background:var(--gdi-line)}
.gdi-market-map{
  position:relative;min-height:420px;background-color:var(--gdi-bg);
  background-image:radial-gradient(circle,color-mix(in srgb,var(--gdi-text) 5%,transparent) 1px,transparent 1px);
  background-size:16px 16px
}
.gdi-market-map canvas{position:absolute;inset:0;width:100%!important;height:100%!important}
.gdi-market-map__empty{margin:0;padding:var(--gdi-gutter);color:var(--gdi-muted)}
/* The market panel's rows are the country's colour, its flag and one figure, so
   the volume sits at the far edge instead of behind a ranked bar. */
/* Every tracked market is listed, and the panel scrolls within the map's height
   rather than stretching the row past it. */
.gdi-market-grid>.gdi-card>.gdi-table-wrap{
  min-height:0;max-height:420px;overflow-y:auto;
  scrollbar-width:thin;scrollbar-color:var(--gdi-line) transparent
}
.gdi-market-grid>.gdi-card>.gdi-table-wrap::-webkit-scrollbar{width:4px}
.gdi-market-grid>.gdi-card>.gdi-table-wrap::-webkit-scrollbar-track{background:transparent}
.gdi-market-grid>.gdi-card>.gdi-table-wrap::-webkit-scrollbar-thumb{background:var(--gdi-line);border-radius:4px}
/* A market name is two or three words in a narrow panel, so it holds its line
   and the panel scrolls instead — a wrapped row would break the run of equal
   row heights the panel beside the map is read against. */
.gdi-markets-table td{padding-left:16px;padding-right:16px;white-space:nowrap}
.gdi-markets-table td:last-child{text-align:right;color:var(--gdi-text)}
/* Only the map card's footer is a single figure, so it sits at the right edge
   with the volumes above it rather than alone on the left. */
.gdi-market-card .gdi-cardfoot{justify-content:flex-end}

/* Two cards side by side rarely hold the same number of rows, so let the body
   absorb the difference and keep both footers on one line. The market pair does
   the same, where five country rows sit beside a full-height map. */
/* min-width:0 is what makes the scrollers inside these cards work. A grid item
   floors at its min-content width by default, so on a phone the widest cell in
   the prompts table sized the track — both cards, and the page with them, came
   out wider than the screen instead of the table scrolling inside its wrap. */
.gdi-tworow>.gdi-card,.gdi-market-grid>.gdi-card{display:flex;flex-direction:column;min-width:0}
.gdi-tworow>.gdi-card>*,.gdi-market-grid>.gdi-card>*{min-width:0}
.gdi-tworow>.gdi-card>.gdi-movegrid,.gdi-tworow>.gdi-card>.gdi-table-wrap,
.gdi-market-grid>.gdi-card>.gdi-table-wrap,.gdi-market-grid>.gdi-card>.gdi-market-map{flex:1 1 auto}

/* Biggest movers: rising and falling share one card, split by the same 1px
   gap rule the other cell grids use. */
.gdi-movegrid{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--gdi-line)}
.gdi-movecol{min-width:0;padding-top:20px;padding-bottom:8px;background:var(--gdi-bg)}
.gdi-movecol--up>.gdi-lbl{color:var(--gdi-green)}
.gdi-movecol--down>.gdi-lbl{color:var(--gdi-red)}
.gdi-movecol>.gdi-lbl{display:block;margin-bottom:4px}
.gdi-movecol .gdi-empty{padding:12px 0;font-size:14px}
.gdi-moverow{display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--gdi-line)}
.gdi-moverow:last-child{border-bottom:0}
.gdi-moverow .gdi-rbar{margin-right:0}
.gdi-moverow__id{flex:1 1 auto;min-width:0}
.gdi-moverow__id .n{display:block;color:var(--gdi-text);line-height:1.2;overflow-wrap:anywhere}
.gdi-moverow__id .s{display:block;margin-top:2px;font-family:var(--gdi-mono);font-size:12px;color:var(--gdi-subtle)}
.gdi-moverow__d{flex-shrink:0;white-space:nowrap}

/* ─── Brand profile diagnostics ─────────────────────────────────────── */
/* Five figures belong to one snapshot. Keeping them on one row at wide
   viewports makes Share of voice a peer of score/rank rather than an addendum;
   the shared responsive rules reduce the grid cleanly below this. */
.gdi-profile-stats{grid-template-columns:repeat(5,1fr)}
.gdi-profile-stats--check{grid-template-columns:repeat(3,1fr)}
.gdi-profile-stats .gdi-ecell{overflow:hidden}
.gdi-placeholder{
  display:inline-flex;align-items:center;margin-left:6px;padding:3px 6px;
  border-radius:2px;background:color-mix(in srgb,var(--gdi-orange) 12%,transparent);
  color:var(--gdi-orange);font-family:var(--gdi-mono);font-size:10px;
  font-style:normal;font-weight:500;line-height:1;text-transform:uppercase;
  vertical-align:2px;white-space:nowrap
}
.gdi-profile-pair{align-items:stretch}
.gdi-profile-pair>.gdi-card{min-width:0}
.gdi-profile-pair .gdi-cardhead{flex:0 0 auto}
.gdi-profile-pair .gdi-cardfoot{margin-top:auto}
.gdi-profile-empty{
  flex:1 1 auto;display:flex;flex-direction:column;align-items:flex-start;
  justify-content:center;min-height:220px;padding:32px var(--gdi-gutter);
  background:var(--gdi-bg);color:var(--gdi-muted)
}
.gdi-profile-empty .gdi-placeholder{margin-left:0}
.gdi-profile-empty p{max-width:440px;margin:16px 0 0}

/* The trend is an inline SVG rather than a chart dependency. It inherits the
   index palette and scales with the card while its viewBox keeps the geometry. */
.gdi-trend{position:relative;padding:20px var(--gdi-gutter);background:var(--gdi-bg)}
.gdi-trend svg{display:block;width:100%;height:auto;min-height:180px}
.gdi-trend__grid{stroke:var(--gdi-line);stroke-width:1}
.gdi-trend polyline{fill:none;stroke:var(--gdi-blue);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
.gdi-trend circle{fill:var(--gdi-bg);stroke:var(--gdi-blue);stroke-width:2}
/* Grown from the centre on hover, so the point the readout is describing is
   obvious without the line moving under it. */
.gdi-trend__dot{transition:r .12s ease}
.gdi-trend__dot.is-on{r:5;fill:var(--gdi-blue)}
/* Parked off the left edge until the script gives it a month to sit on. */
.gdi-trend__guide{stroke:var(--gdi-line);stroke-width:1;opacity:0}
.gdi-trend.is-hovering .gdi-trend__guide{opacity:1}
/* The readout the Chart.js line on the index page shows, rebuilt to sit over an
   inline SVG: same panel, same muted label over a bright figure. It is anchored
   to the dot's centre, so the transform lifts it clear and re-centres it. */
.gdi-trend__tip{
  /* Never a hover target itself: it is anchored above the point it describes
     and overlaps the plot, so catching the pointer would drop the hover that
     put it there and set it flickering. */
  position:absolute;z-index:2;pointer-events:none;opacity:0;visibility:hidden;
  transform:translate(-50%,calc(-100% - 12px));
  display:flex;flex-direction:column;gap:2px;padding:10px 12px;white-space:nowrap;
  background:#323232;color:#fafafa;font-size:13px;line-height:1.3;
  transition:opacity .12s ease
}
.gdi-trend.is-hovering .gdi-trend__tip{opacity:1;visibility:visible}
.gdi-trend__tip-label{font-family:var(--gdi-mono);font-size:11px;text-transform:uppercase;color:#a3a3a3}
.gdi-trend__tip strong{font-weight:600}
.gdi-trend__tip-note{margin-top:2px;font-size:11px;color:#a3a3a3}
.gdi-trend__axis{
  display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:8px;
  font-family:var(--gdi-mono);font-size:11px;line-height:1.3;text-transform:uppercase;color:var(--gdi-subtle)
}
.gdi-trend__axis span:nth-child(2){text-align:center}
.gdi-trend__axis span:last-child{color:var(--gdi-text)}

.gdi-engine-scores td:first-child{display:flex;align-items:center;gap:10px;white-space:nowrap}
.gdi-engine-scores .gdi-engine-icon{margin:0}
.gdi-engine-scores td:nth-child(2){width:100%}
.gdi-profile-cut{font-family:var(--gdi-mono)!important;font-size:11px;text-transform:uppercase;white-space:nowrap}
.gdi-profile-prompts td:first-child{width:100%}
.gdi-profile-prompts .gdi-trackwrap{justify-content:flex-end}
.gdi-profile-industries{min-width:760px}
.gdi-profile-industries tr.is-current{background:var(--gdi-hover)}
.gdi-profile-industries .gdi-chip{margin-left:8px}

/* Compact table: same rails, shorter rows, for the small cards in a two-up row.
   Rows size to their content, which lets a long prompt wrap onto a second line
   instead of overflowing the fixed height the full-width tables use. */
.gd-index table.gdi-compact th,.gd-index table.gdi-compact td{height:auto;padding-top:12px;padding-bottom:12px}
/* A floor, not a fixed height: on a table cell, height is the minimum. The two
   cards in a two-up row hold different things per row — a chip, an icon, a bare
   figure — and without this each card set its own rhythm and the pair stopped
   lining up rule for rule. 28px is the chip, the tallest of them, so no row that
   fits on one line has to grow past it, and a wrapped prompt still takes the
   second line it needs. Stated as 53px because the theme sets border-box, so
   the figure has to carry the 12px padding either side and the 1px rule under
   the row as well as the chip itself. */
.gd-index table.gdi-compact td{height:53px;line-height:20px}
/* The icon is the same 20px as the line box, but inline layout hangs its descent
   below the baseline on top of that, which pushed rows carrying one half a pixel
   past the floor. Collapsing the margin box keeps it out of the line box's
   height while it still paints in place. */
.gd-index table.gdi-compact .gdi-favicon,
.gd-index table.gdi-compact .gdi-flag{vertical-align:middle;margin-top:-10px;margin-bottom:-10px}
/* Centred for the same reason: sitting on the baseline, the chip's own descent
   put it half a pixel over the floor, and half a pixel a row is a visible drift
   by the fifth one. */
.gd-index table.gdi-compact .gdi-chip{vertical-align:middle}
/* Half-width cards leave the text column little room, so the figures beside it
   hold only what they need and the prompt or topic takes the rest. */
.gd-index table.gdi-compact th:not(:first-child):not(:nth-child(2)),
.gd-index table.gdi-compact td:not(:first-child):not(:nth-child(2)){width:1%;white-space:nowrap}
/* Spans both columns so the painted whitespace closes the row full width. */
.gdi-tworow::after{content:"";grid-column:1/-1;height:var(--gdi-rhythm);background:var(--gdi-bg)}
/* A two-up row inside a section takes that section's closing rhythm rather than
   adding its own, which would open a second gap before the section even ends. */
.gdi-sec>.gdi-tworow::after{content:none}

/* ─── Split bands ────────────────────────────────────────────────────── */
/* Running copy composed the way the FAQ under it is — a heading column beside a
   column of rows — but mirrored: the statements lead and the heading closes the
   band on the right. Each statement is already a self-contained sentence, so
   they read as rows rather than as a paragraph broken up.
   Every rule is a 1px gap over the band's line colour, not a border: the one
   between the two columns, and the ones dividing the rows. They meet the
   section rules above and below like every other rule on the page.
   The band carries its own heading, so these sections take no .gdi-sechead —
   the same trade the FAQ block makes, and the reason the two read as a pair. */
.gdi-split{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--gdi-line)}
/* Placed rather than ordered: the heading leads in the markup, where reading
   order needs it, and moves to the second column only once there are two. */
/* Centred against the rows beside it, which are the taller column in practice
   — the heading is two short lines and would otherwise sit high in a cell sized
   by its neighbour. */
.gdi-split__head{
  grid-column:2;grid-row:1;min-width:0;display:flex;flex-direction:column;
  justify-content:center;background:var(--gdi-bg);
  padding-top:40px;padding-bottom:40px
}
.gdi-split__head>.gdi-lbl{display:block;color:var(--gdi-blue)}
/* A step below the hero's clamp: this is the band's own statement, so it sits
   well above a section heading rather than matching one. */
.gdi-split__head h2{
  margin:16px 0 0;font-size:clamp(1.75rem,2.5vw,2.25rem);font-weight:600;
  line-height:1.1;letter-spacing:-.02em;color:var(--gdi-text)
}
.gdi-split__rows{
  grid-column:1;grid-row:1;display:flex;flex-direction:column;gap:1px;
  min-width:0;background:var(--gdi-line)
}
/* Absorbs the slack when the heading column is the taller of the two, so the
   rules between rows stay evenly spread instead of bunching at the top. */
.gdi-splitrow{
  flex:1 1 auto;display:flex;flex-direction:column;justify-content:center;
  padding-top:24px;padding-bottom:24px;background:var(--gdi-bg);
  font-size:16px;line-height:1.6;color:var(--gdi-muted)
}
/* Keeps the sentence a single flex item, so its inline emphasis stays inline
   instead of each <b> breaking onto a line of its own. */
.gdi-splitrow p{margin:0}
.gdi-splitrow b{color:var(--gdi-text);font-weight:600}
/* The finding-and-evidence row. Laid across rather than down so the chip can
   close it, with the copy stacked inside its own box: the two lines belong to
   each other and would otherwise become flex items either side of the chip. */
.gdi-splitrow--pair{flex-direction:row;align-items:center;justify-content:space-between;gap:24px}
/* Capped at the measure the rest of the page's prose takes. Between the point
   the band drops to one column and the point the chip moves above the copy, the
   row is wide enough that a sentence would otherwise run the full width and
   leave the chip stranded a long way from what it labels. */
.gdi-splitrow__body{min-width:0;max-width:600px}
.gdi-splitrow--pair .gdi-splitrow__title{color:var(--gdi-text);font-weight:600}
/* Scoped past .gdi-splitrow p, which zeroes the margin on every paragraph in a
   row and would otherwise outrank a bare class here and close this gap. */
.gdi-splitrow--pair .gdi-splitrow__detail{margin-top:4px}
/* A rail rather than a hug: left to size itself, each chip's left edge lands
   wherever its own label ends and the column reads ragged down the band. A
   floor, not a fixed width, so a longer label than today's still fits. */
.gdi-splitrow--pair .gdi-chip{flex:0 0 auto;justify-content:center;min-width:76px}
/* The pitch form of the band, where the heading column also has to ask for
   something. The blurb takes the section note's measure so it stays a line or
   two under the statement rather than becoming a column of its own. */
.gdi-split__sub{max-width:44ch;margin:16px 0 0;font-size:16px;line-height:1.5;color:var(--gdi-muted)}
/* The theme button brings its own size and its own centring wrapper; the column
   only has to release the centring and set the gap above it. */
.gdi-split__cta{display:flex;margin-top:24px}
.gdi-split__cta .btn-wrapper{margin-top:0}

/* ─── Prose ──────────────────────────────────────────────────────────── */
/* The measure is capped on the paragraphs, not the panel: as a painted child of
   a line-coloured card, a narrow panel would let the line colour show beside it.
   48.75rem is the measure the theme sets on article bodies in
   styles/layout/_single-blog.scss, so running copy here reads at the same line
   length as running copy anywhere else on the site. */
.gdi-prose{padding-top:24px;padding-bottom:24px;font-size:16px;line-height:1.6;color:var(--gdi-body)}
.gdi-prose p{max-width:48.75rem;margin:0 0 16px}
.gdi-prose p:last-child{margin-bottom:0}
.gdi-prose b,.gdi-prose strong{color:var(--gdi-text);font-weight:600}
/* Long-form, admin-edited content (the methodology page's own WP Page body)
   needs heading/list styles .gdi-prose never had to carry before — every
   other user of the class was plain generated paragraphs. */
.gdi-prose--article h2{
  max-width:48.75rem;margin:40px 0 12px;font-size:24px;font-weight:600;
  line-height:1.2;letter-spacing:-.02em;color:var(--gdi-text)
}
.gdi-prose--article h2:first-child{margin-top:0}
.gdi-prose--article h3{max-width:48.75rem;margin:24px 0 8px;font-size:19px;font-weight:600;line-height:1.3;color:var(--gdi-text)}
.gdi-prose--article ul,.gdi-prose--article ol{max-width:48.75rem;margin:0 0 16px;padding-left:1.25em}
.gdi-prose--article li{margin-bottom:6px}
.gdi-prose--article a{color:var(--gdi-blue)}
/* Anchor targets sit right under the fixed rail, so a click from the TOC
   below doesn't land the heading flush against the viewport edge. */
.gdi-prose--article h2[id],.gdi-prose--article h3[id]{scroll-margin-top:24px}

/* Table of contents: the same sidebar widget the blog runs beside every
   article via the Joli TOC plugin (see .wpj-jtoc in
   styles/layout/_single-post-template.scss) — sticky on desktop, a
   collapsible <details> with nested <ol>s for h2/h3, restyled on the
   Index's own dark tokens rather than the blog's Bootstrap ones, since
   this page lives inside .gd-index's own design system. */
.gdi-methodology-layout{display:grid;grid-template-columns:240px 1fr}
.gdi-methodology-layout--no-toc{grid-template-columns:1fr}
/* The blog's border sits on the full-height sidebar column, not on its
   sticky inner box — checked via computed styles (border-right:1px solid
   rgb(50,50,50), i.e. --gdi-line, on .single-post-template__sidebar) — so
   it runs the whole length of the article. .gdi-methodology-toc is that
   column here (a plain grid item, stretched to the row's full height by
   default); .gdi-toc is the sticky box inside it and carries no border of
   its own. */
.gdi-methodology-toc{border-right:1px solid var(--gdi-line)}
/* Padding/gaps below are the blog widget's own measured values (its wrap is
   40px 16px, items sit 21px apart, sub-items 12px), not gd-index's usual
   --gdi-gutter/rhythm — this component is deliberately copying that one.
   top:102px matches the blog's own measured sticky offset: its 71px sticky
   header plus the same breathing room, so the box doesn't stick flush
   against it while scrolling. */
.gdi-toc{padding:40px 16px;position:sticky;top:102px}
.gdi-toc__head{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  list-style:none;cursor:pointer;color:var(--gdi-text);font-size:15.5px;font-weight:800
}
.gdi-toc__head::-webkit-details-marker{display:none}
/* A literal +/− toggle, matching the blog's own widget exactly rather than
   a chevron: two bars form the +, and the vertical one collapses to 0 to
   leave the − once open. */
.gdi-toc__icon{position:relative;flex:0 0 auto;width:14px;height:14px}
.gdi-toc__icon::before,.gdi-toc__icon::after{
  content:"";position:absolute;top:50%;left:50%;background:var(--gdi-text);
  transform:translate(-50%,-50%);transition:transform .15s ease
}
.gdi-toc__icon::before{width:14px;height:1.5px}
.gdi-toc__icon::after{width:1.5px;height:14px}
.gdi-toc[open] .gdi-toc__icon::after{transform:translate(-50%,-50%) scaleY(0)}
.gdi-toc__body{margin-top:20px}
.gdi-toc__list{display:flex;flex-direction:column;gap:20px;margin:0;padding:0;list-style:none}
/* !important to beat .gd-index a:not(.btn)'s color:var(--gdi-blue) default —
   same reason .gdi-ent needs it for the site's other entity links. */
.gdi-toc__list a{display:block;font-size:15px;font-weight:600;line-height:1.3;color:var(--gdi-subtle)!important;transition:color .15s ease}
.gdi-toc__list a:hover,.gdi-toc__list a.on{color:var(--gdi-text)!important;text-decoration:none}
.gdi-toc__list--sub{gap:12px;margin-top:12px;margin-left:20px}
.gdi-toc__list--sub a{font-size:14px;font-weight:400;color:var(--gdi-subtle)!important}
.gdi-toc__list--sub a:hover,.gdi-toc__list--sub a.on{color:var(--gdi-text)!important}

/* CTA sits as the boxes' own footer, not in the leftover slab the section
   used to paint below them. The boxes already draw the rule above this row. */
.gdi-method__more{
  display:flex;justify-content:center;align-items:center;
  margin:0;padding:24px var(--gdi-gutter);
  border-bottom:1px solid var(--gdi-line)
}

/* The FAQ is the theme's own block, rendered by gd_index_faq_block_html(), and
   takes no overrides here: it is the same section as every other FAQ on the
   site, down to the padding its heading column sits in. */

/* ─── CTA, check, gate, methodology ──────────────────────────────────── */
.gdi-cta{
  display:flex;align-items:center;justify-content:space-between;gap:32px;min-height:160px;
  padding-top:24px;padding-bottom:24px
}
.gdi-cta h3,.gdi-check h2,.gdi-gate h2{margin:0 0 8px;font-size:24px;font-weight:600;line-height:1.1;letter-spacing:-.48px}
.gdi-cta p,.gdi-check .sub,.gdi-gate p{max-width:600px;margin:0;font-size:16px;line-height:1.5;color:var(--gdi-muted)}
.gdi-actions{display:flex;flex-wrap:wrap;gap:2px}
.gdi-btn{
  display:inline-flex;align-items:center;justify-content:center;height:48px;padding:0 24px;
  border:0;border-radius:8px;font:16px/1.2 var(--gdi-font);white-space:nowrap;cursor:pointer;
  transition:opacity .15s ease,transform .1s ease
}
.gdi-btn-b{background:var(--gdi-blue);color:var(--color-black)!important}
.gdi-btn-o,.gdi-btn-w{background:var(--gdi-line);color:var(--gdi-text)!important}
.gdi-btn:hover{opacity:.86;text-decoration:none!important}
.gdi-btn:active{transform:scale(.97)}
/* Two cells split by the same 1px gap the rest of the page draws its rules
   with: the prompt on the left, and what the check returns on the right so the
   band earns its width instead of leaving half of it empty. */
.gdi-check{display:flex;gap:1px;background:var(--gdi-line)}
/* A gap-drawn stack for the same reason the right column is one: the rule above
   the figures has to run the full width of the cell and meet the divider beside
   it. As a border inside the padded cell it stopped a gutter short at both ends. */
.gdi-check__main{
  flex:1 1 58%;min-width:0;display:flex;flex-direction:column;gap:1px;background:var(--gdi-line)
}
.gdi-check__body{flex:1 1 auto;padding:40px var(--gdi-gutter);background:var(--gdi-bg)}
/* Direct child only — the eyebrow reads as an accent like the hero's, while the
   right column's label stays a plain muted caption. It also has to be a block:
   left inline it sits in an anonymous box whose strut comes from the body's
   line-height, which added ~8px of phantom leading under its own line-height:1
   and made the gap to the heading larger than the 16px set below. */
.gdi-check__body>.gdi-lbl{display:block;color:var(--gdi-blue)}
.gdi-check h2{margin-top:16px}
/* The right column is a gap-drawn stack like the hero's figures, so its rules
   run the full width of the cell and meet the divider beside them. Padding the
   list and using borders instead would leave every rule short at both ends. */
.gdi-check__proof{
  flex:1 1 42%;min-width:0;display:flex;flex-direction:column;gap:1px;background:var(--gdi-line)
}
.gdi-check__proof ul{display:contents;margin:0;padding:0;list-style:none}
.gdi-check__proofhead{
  display:flex;align-items:center;flex:0 0 auto;
  min-height:56px;padding:16px var(--gdi-gutter);background:var(--gdi-bg)
}
.gdi-check__proof li{
  display:flex;align-items:center;flex:1;min-height:72px;padding:16px var(--gdi-gutter);
  background:var(--gdi-bg);font-size:19px;font-weight:500;line-height:1.2;
  letter-spacing:-.38px;color:var(--gdi-text)
}

/* Matches the field on the audit and llms.txt tools: one rounded surface holds
   the input and its button, rather than two adjacent controls. */
/* margin-top is 20 rather than 24 because .sub sets line-height:1.5 on 16px type
   and so carries 4px of half-leading below its last line, so 20 + 4 is what
   reads as 24 against the cell's padding below. */
.gdi-field{
  display:flex;align-items:center;gap:12px;height:64px;width:min(100%,480px);padding:12px;
  margin-top:20px;border:1px solid var(--gdi-line-strong);border-radius:12px;
  background:var(--gdi-line);transition:background-color .15s ease
}
.gdi-field:focus-within{background:color-mix(in srgb,var(--gdi-blue) 5%,var(--gdi-line))}
.gdi-field__input{
  flex:1 1 auto;min-width:0;height:auto;padding:0 0 0 8px;border:0;outline:none;
  background:transparent;color:var(--gdi-text);font:16px/1.2 var(--gdi-font)
}
.gdi-field__input::placeholder{color:var(--gdi-subtle)}
.gdi-btn--field{flex:0 0 auto;height:40px;padding:0 20px;border-radius:8px}
/* The theme's button arrives inside its own flex wrapper, which would otherwise
   stretch and share the row's free space with the input. */
.gdi-field .btn-wrapper{flex:0 0 auto}
.gdi-check__meta{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px 20px;
  min-height:56px;padding:16px var(--gdi-gutter);background:var(--gdi-bg);
  font-family:var(--gdi-mono);
  font-size:11px;letter-spacing:.02em;text-transform:uppercase;color:var(--gdi-subtle)
}
.gdi-check__meta b{color:var(--gdi-muted);font-weight:400}
.gdi-gaplist{padding-top:8px;padding-bottom:8px}
.gdi-gapitem{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:64px;padding:12px 0;border-bottom:1px solid var(--gdi-line)}
.gdi-gapitem:last-child{border-bottom:0}
.gdi-gapitem .g2{margin-top:4px;font-size:16px;color:var(--gdi-muted)}
.gdi-gate{padding:64px var(--gdi-gutter);text-align:center}
.gdi-gate p{margin:0 auto 24px}
/* The closing methodology band is the site's own article-content component.
   Its title and boxes already carry their own padding, so this wrapper does
   not add another rhythm slab — that was stacking on the component and
   leaving the CTA floating in empty space. */
.gdi-method{background:var(--gdi-bg)}
.gdi-method .component-article-content__inner{padding-top:48px;padding-bottom:40px}
.gdi-method .component-article-content__boxes-row{width:100%}
.gdi-method .component-article-content__box{padding-top:32px;padding-bottom:32px}

@media(max-width:1100px){
  .gd-index{--gdi-rhythm:64px}
  .gdi-eviden,.gdi-eviden--three,.gdi-indgrid,.gdi-profile-stats{grid-template-columns:repeat(2,1fr)}
  .gdi-tworow{grid-template-columns:1fr}
  /* One column: the heading goes back to leading its own rows, which is the
     order the markup is already in, so both placements are released. */
  .gdi-split{grid-template-columns:1fr}
  .gdi-split__head,.gdi-split__rows{grid-column:1;grid-row:auto}
  .gdi-split__head{padding-top:32px;padding-bottom:32px}
  .gdi-check{flex-direction:column}
  /* The blog's own TOC widget does the same thing below its own equivalent
     breakpoint: it doesn't switch to a different control, it just stops
     being a sticky sidebar and stacks as the same widget, full width, above
     the article — and its column border-right becomes a full border box
     around the widget itself instead (matching the blog's own SCSS). */
  .gdi-methodology-layout{grid-template-columns:1fr}
  .gdi-methodology-toc{border-right:0}
  .gdi-toc{position:static;padding-top:20px;padding-bottom:20px;border:1px solid var(--gdi-line)}
}
/* The component drops the flanks at 1023px rather than squeezing them, so the
   copy column stops relying on their height for its own. The hub's model field
   goes with them, and its figures band stacks into single-column rows. */
@media(max-width:1023px){
  .gdi-hero__content{min-height:0;padding:97px 24px 72px}
  .gdi-hero__mosaic{display:none}
  .gdi-hero__band{flex-direction:column}
  /* Two across instead of three: below this a third of the rail is narrower
     than the prose inside a cell needs. Rows go back to content height, since
     forcing three equal rows would pad the short ones out badly. */
  .gdi-bench{grid-template-columns:repeat(2,1fr);grid-auto-rows:auto}
}
@media(max-width:767px){
  .gd-index{--gdi-gutter:16px;--gdi-rhythm:40px;padding:0 0 64px}
  /* Desktop keeps the full trail. Here the hub crumb plus an industry name
     wraps onto two lines with a stranded chevron, so anything deeper than
     parent › current is dropped — the hub is still in JSON-LD and one tap
     from the remaining parent link. Two-item trails stay as they are. */
  .gdi-crumbs ol{flex-wrap:nowrap}
  .gdi-crumbs ol:has(li:nth-child(3)) .gdi-crumbs__item:not(:nth-last-child(-n+2)){display:none}
  .gdi-crumbs__item:not(:last-child){min-width:0}
  .gdi-crumbs__item:not(:last-child) a{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .gdi-hero__content{padding:80px 20px 72px}
  .gdi-hero__stat{min-height:72px;padding:0 16px}
  .gdi-hero__stat-value{font-size:24px}
  /* Still clearing the overhanging hero badge, which stays absolute here. */
  .gdi-edition__body{padding-top:48px;padding-bottom:24px;font-size:16px}
  /* Wrapping split the label off its value onto a ragged second line, so the
     badge stays on one line and gives up a point of type instead. */
  .gdi-hero__badge{height:auto;min-height:40px;padding:12px 16px;font-size:11px}
  .gdi-sechead,.gdi-cardhead{flex-direction:column;align-items:flex-start;gap:8px;min-height:0;padding-top:20px;padding-bottom:20px}
  .gdi-market-grid{grid-template-columns:1fr}.gdi-market-map{min-height:280px}
  .gdi-sechead h2{font-size:19px;letter-spacing:-.38px}
  /* Same trade the headers above make: at this width the chip beside the copy
     costs more measure than it is worth, so it becomes a label over the finding
     and the sentence gets the full column back. */
  .gdi-splitrow--pair{flex-direction:column;align-items:flex-start;gap:8px}
  .gdi-splitrow--pair .gdi-chip{order:-1}
  .gdi-sectools{flex:0 0 auto;width:100%}
  .gdi-eviden,.gdi-eviden--three,.gdi-eviden--two,.gdi-indgrid,.gdi-bench,.gdi-movegrid,.gdi-profile-stats{grid-template-columns:1fr}
  /* The engine columns stack instead of scrolling sideways: four of them at a
     240px floor never fit a phone, so the scroller left every column half-cut
     and the ranking under it unreadable. Stacked, each engine gets the full
     width and the 1px gaps that drew the column rules draw the rows between
     them. overflow-x is released so the card stops reserving a scrollbar. */
  .gdi-mgrid{grid-auto-flow:row;grid-template-columns:1fr;overflow-x:visible}
  .gdi-bcell,.gdi-ecell,.gdi-mcol,.gdi-prose,.gdi-splitrow{padding-top:20px;padding-bottom:20px}
  .gdi-split__head{padding-top:24px;padding-bottom:24px}
  .gdi-split__head h2{margin-top:12px;font-size:19px;letter-spacing:-.38px}
  .gdi-movecol{padding-top:16px;padding-bottom:8px}
  .gdi-bcell .bv,.gdi-ecell .ev{font-size:32px}
  .gd-index th,.gd-index td{height:56px;padding-top:12px;padding-bottom:12px;font-size:14px}
  /* Scroll rather than reflow. These tables already sit in a scroller, and at
     this width reflowing broke a domain off its own favicon onto a second line
     and set every row to a different height. Only cells inside .gdi-table-wrap:
     a table without the scroller has nowhere for the overflow to go. */
  .gd-index .gdi-table-wrap th,.gd-index .gdi-table-wrap td{white-space:nowrap}
  .gdi-rank{width:44px}
  .gdi-rbar{margin-right:12px}
  .gdi-cardfoot{flex-direction:column;align-items:flex-start;gap:8px;font-size:14px}
  /* Icon chips, with the selected one expanding to show its name. Unselected
     pills used to shrink (flex default) inside overflow:hidden, which clipped
     "All models" to "All mode" instead of letting the row scroll. */
  .gdi-sorter{
    flex-wrap:nowrap;gap:6px;width:100%;max-width:100%;
    overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none
  }
  .gdi-sorter::-webkit-scrollbar{display:none}
  .gd-index .gdi-sbtn{
    flex:0 0 auto;width:36px;padding:0;white-space:nowrap
  }
  .gd-index .gdi-sbtn.on{width:auto;padding:0 16px}
  .gd-index .gdi-sbtn.on:has(.gdi-engine-icon){padding:0 14px 0 10px}
  .gdi-sbtn__mark{display:flex;align-items:center;justify-content:center;width:14px;height:14px;flex-shrink:0}
  .gd-index .gdi-sbtn.on .gdi-sbtn__mark{display:none}
  /* Parked on the chip's own centre rather than in the flex row: a 1px
     clipped label as a sibling still took a gap slot and shifted the icon. */
  .gd-index .gdi-sbtn:not(.on){gap:0}
  .gd-index .gdi-sbtn:not(.on) .gdi-sbtn__label{
    position:absolute;left:50%;top:50%;width:1px;height:1px;padding:0;margin:0;
    overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0
  }
  .gd-index .gdi-sbtn .gdi-engine-icon{width:18px;height:18px;object-fit:contain}
  .gdi-check__body{padding-top:32px;padding-bottom:32px}
  .gdi-check__proofhead{min-height:48px;padding:12px var(--gdi-gutter)}
  .gdi-check__proof li{min-height:64px;padding:12px var(--gdi-gutter);font-size:16px}
  /* The field keeps the input and button side by side down to the smallest
     width, the same as the audit and llms.txt tools, and keeps their 12px
     padding so its inner insets don't go lopsided. Only the button gives up
     width, which is what the audit tool does with min-width:0. */
  .gdi-field{width:100%}
  .gdi-btn--field{padding:0 16px}
  .gdi-cta{flex-direction:column;align-items:flex-start;gap:24px;min-height:0}
  .gdi-trend{padding-top:16px;padding-bottom:16px}
  .gdi-trend svg{min-height:140px}
  .gdi-gate{padding:40px var(--gdi-gutter)}
}
