/*
 * Interview Questions v2 — "Study Companion" visual restyle
 * Instrument panel background, Instrument Sans, Fragment Mono indices, single-orange accent.
 * Component prefix: .iq-*  (interview questions). Loaded alongside the legacy
 * interview-questions.css so the legacy fallback states (picker pages, search
 * results) keep working unchanged.
 */

/* ---------- Tokens (kept here too as CSS vars so non-Tailwind contexts can use them) ---------- */
:root {
   --iq-paper:    #E9E8E3;
   --iq-paper2:   #DFDDD7;
   --iq-card:     #F8F7F4;
   --iq-cardEdge: #C9C7C0;
   --iq-rule:     #D6D4CD;
   --iq-rule2:    #C9C7C0;
   --iq-divider:  #DFDDD7;

   --iq-ink:  #232320;
   --iq-ink2: #45443E;
   --iq-ink3: #67665F;
   --iq-ink4: #94938B;
   --iq-ink5: #B5B4AC;

   --iq-accent:  #E55A12;
   --iq-accentD: #C24A0B;
   --iq-accentS: #F3E2D2;
   --iq-accentE: #E5C4A4;

   --iq-green:  #256E4C; --iq-greenS: #E0EAE2; --iq-greenDot: #2E9E6B;
   --iq-amber:  #7D5A0B; --iq-amberS: #F2E8CE; --iq-amberDot: #D9A013;
   --iq-rose:   #9E3D2B; --iq-roseS:  #F0E0DA; --iq-roseDot:  #C4442E;

   --iq-dark:   #232320;
   --iq-darkD:  #1B1B18;
}

/* ---------- Page-level (only when v2 root is present) ---------- */
.iq-v2 {
   background: var(--iq-paper);
   color: var(--iq-ink);
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
}

.iq-v2 ::selection {
   background: var(--iq-accentS);
   color: var(--iq-accentD);
}

/* ---------- Breadcrumb ---------- */
.iq-breadcrumb {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 13.5px;
   color: var(--iq-ink3);
   padding: 14px 0;
   display: flex;
   align-items: center;
   gap: 6px;
   flex-wrap: wrap;
}
.iq-breadcrumb a {
   color: var(--iq-ink3);
   text-decoration: none;
   transition: color .15s ease;
}
.iq-breadcrumb a:hover { color: var(--iq-ink); }
.iq-breadcrumb .iq-bc-sep {
   color: var(--iq-ink4);
   margin: 0 2px;
}
.iq-breadcrumb .iq-bc-current {
   color: var(--iq-ink);
   font-weight: 600;
}
/* Detail pages opt in (breadcrumb.ejs hideCurrentOnMobile): on phones the
   current-page crumb duplicates the H1 directly below it and cost ~3 lines
   of the first viewport - hide it and its separator, keep the tappable
   ancestor trail. Structured data still carries the full trail. */
@media (max-width: 640px) {
   /* Two rules on purpose: one unsupported selector voids a whole selector
      LIST, so grouping these would lose the crumb-hide wherever :has() is
      missing. Split, the crumb always hides; the trailing separator cleanup
      is progressive enhancement. */
   .bc-hide-current-sm .iq-bc-current { display: none; }
   .bc-hide-current-sm .iq-bc-sep:has(+ .iq-bc-current) { display: none; }
}

/* ---------- Hero ----------
   Layout note: stats sit on a single header row alongside the eyebrow (top-aligned
   condensed cluster) rather than being bottom-aligned in a right column. Lets the
   H1 + subhead take the full content width without leaving a dead-space gap when
   the title is short ("React.") or the stats are absent (category state). */
.iq-hero {
   padding: 28px 0 26px;
   border-bottom: 1px solid var(--iq-rule);
}
.iq-hero-head {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 16px;
   margin-bottom: 14px;
   flex-wrap: wrap;
}
.iq-hero-eyebrow {
   display: inline-flex;
   align-items: center;
   gap: 6px;
   padding: 5px 10px;
   background: var(--iq-accentS);
   color: var(--iq-accentD);
   border-radius: 999px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 12px;
   font-weight: 700;
   letter-spacing: 0.06em;
   text-transform: uppercase;
}
.iq-hero h1, .iq-hero .iq-hero-title {
   font-family: 'Instrument Sans', system-ui, sans-serif;
   font-weight: 700;
   letter-spacing: -0.035em;
   line-height: 1.02;
   color: var(--iq-ink);
   font-size: 36px;
   margin: 0;
   max-width: 18ch;
}
@media (min-width: 880px) {
   .iq-hero h1, .iq-hero .iq-hero-title { font-size: 52px; }
}
.iq-hero .iq-accent-char { color: var(--iq-accent); }
.iq-hero-foot {
   margin-top: 14px;
   display: flex;
   justify-content: space-between;
   align-items: baseline;
   gap: 12px 32px;
   flex-wrap: wrap;
}
.iq-hero-sub {
   margin: 0;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 16.5px;
   line-height: 1.55;
   color: var(--iq-ink3);
   max-width: 60ch;
}

.iq-stats {
   display: flex;
   gap: 22px;
   align-items: baseline;
   flex-wrap: wrap;
   flex: 0 0 auto;
}
.iq-stat {
   display: inline-flex;
   align-items: baseline;
   gap: 6px;
}
.iq-stat-num {
   font-family: 'Instrument Sans', system-ui, sans-serif;
   font-weight: 600;
   font-size: 18px;
   letter-spacing: -0.035em;
   line-height: 1;
   color: var(--iq-ink);
}
.iq-stat-num.iq-stat-num-accent  { color: var(--iq-accent); }
.iq-stat-num.iq-stat-num-muted   { color: var(--iq-ink4); }
.iq-stat-label {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   font-weight: 400;
   letter-spacing: 0.08em;
   text-transform: uppercase;
   color: var(--iq-ink3);
}

/* ---------- Route-change progress bar ----------
   Thin indeterminate bar that fires when the user clicks a rail link
   (Category pill or Stack tile). Activated by JS via .is-active; the
   bar persists in the old DOM until the new page replaces it, so the
   user gets visual feedback during full-page navigation. */
.iq-route-progress {
   position: fixed;
   top: 0;
   left: 0;
   width: 100%;
   height: 2px;
   z-index: 9999;
   pointer-events: none;
   overflow: hidden;
   opacity: 0;
   transition: opacity .12s ease;
}
.iq-route-progress.is-active { opacity: 1; }
.iq-route-progress::before {
   content: '';
   display: block;
   width: 35%;
   height: 100%;
   background: var(--iq-accent);
   animation: iqRouteProgress 1.1s cubic-bezier(.4, 0, .2, 1) infinite;
}
@keyframes iqRouteProgress {
   0%   { transform: translateX(-100%); }
   100% { transform: translateX(380%); }
}

/* ---------- Browse Rail ---------- */
.iq-rail {
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 14px;
   margin: 18px 0;
   overflow: hidden;
}
.iq-rail-header {
   display: flex;
   align-items: center;
   gap: 12px;
   width: 100%;
   padding: 14px 16px;
   background: transparent;
   border: 0;
   cursor: pointer;
   font-family: 'Instrument Sans', sans-serif;
   color: var(--iq-ink2);
   text-align: left;
   transition: background .15s ease;
}
.iq-rail-header:hover { background: var(--iq-paper); }
.iq-rail-eyebrow {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   font-weight: 400;
   letter-spacing: 0.1em;
   text-transform: uppercase;
   color: var(--iq-ink3);
}
.iq-rail-path {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 13.5px;
   color: var(--iq-ink2);
   margin-left: auto;
}
.iq-rail-path .iq-rail-current { color: var(--iq-ink); font-weight: 600; }
.iq-rail-chevron {
   margin-left: auto;
   transition: transform .2s ease;
   color: var(--iq-ink3);
}
.iq-rail-path + .iq-rail-chevron { margin-left: 0; }
.iq-rail-chevron.is-open { transform: rotate(180deg); }
.iq-rail-body {
   padding: 4px 16px 18px;
   border-top: 1px solid var(--iq-divider);
}
.iq-rail-section {
   margin-top: 14px;
}
.iq-rail-section-label {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   font-weight: 400;
   letter-spacing: 0.1em;
   text-transform: uppercase;
   color: var(--iq-ink3);
   margin-bottom: 10px;
}
.iq-cat-pills {
   display: flex;
   flex-wrap: wrap;
   gap: 8px;
}
.iq-cat-pill {
   display: inline-flex;
   align-items: center;
   padding: 9px 16px;
   border-radius: 999px;
   border: 1px solid transparent;
   background: var(--iq-paper2);
   color: var(--iq-ink);
   font-family: 'Instrument Sans', sans-serif;
   font-size: 15px;
   font-weight: 500;
   text-decoration: none;
   transition: all .15s ease;
   cursor: pointer;
}
.iq-cat-pill:hover {
   background: var(--iq-rule);
   color: var(--iq-ink);
}
.iq-cat-pill.is-active {
   background: var(--iq-dark);
   color: var(--iq-paper);
   border-color: var(--iq-dark);
}
.iq-tech-grid {
   display: grid;
   grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
   gap: 10px;
}
@media (max-width: 879px) {
   .iq-tech-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 8px; }
}
.iq-tech-tile {
   display: flex;
   align-items: center;
   gap: 12px;
   padding: 12px 14px;
   border-radius: 10px;
   border: 1px solid var(--iq-cardEdge);
   background: var(--iq-card);
   color: var(--iq-ink);
   font-family: 'Instrument Sans', sans-serif;
   font-size: 15px;
   font-weight: 500;
   text-decoration: none;
   transition: all .15s ease;
   min-height: 56px;
}
/* Tile label: clamp to 2 lines and keep tile heights even across the grid.
   Long topic labels like "Resilience Patterns (Circuit Breaker, Retry)" used
   to wrap to 4 lines next to single-word tiles ("API Design") on the same
   row, producing a jagged grid. */
.iq-tech-label {
   display: -webkit-box;
   /* 3 lines, not 2: utils/topicLabel strips trailing parentheticals, but a
      handful of titles are genuinely long with nothing to drop ("System
      Administration Fundamentals"). Truncating a tile's own name is worse than
      an uneven row. */
   -webkit-line-clamp: 3;
   -webkit-box-orient: vertical;
   overflow: hidden;
   line-height: 1.25;
   min-width: 0;
   flex: 1;
   /* Safety net: line-clamp + overflow:hidden clips a too-long word
      horizontally rather than wrapping it, which reads as a rendering bug. */
   overflow-wrap: break-word;
}

/* ── Browse counts ─────────────────────────────────────────────────────────
   Every chip and tile says how much is behind it. Without these the picker was
   forty unlabelled doors: you could not tell a 3-question topic from a
   200-question one, so the depth of the library was invisible. */
.iq-tile-count {
   flex: none;
   margin-left: auto;
   padding-left: 8px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11px;
   font-weight: 400;
   line-height: 1;
   color: var(--iq-ink4);
   font-variant-numeric: tabular-nums;
}
.iq-tech-tile:hover .iq-tile-count,
.iq-topic-tile:hover .iq-tile-count { color: var(--iq-ink3); }
.iq-tech-tile.is-active .iq-tile-count { color: var(--iq-paper); opacity: .7; }
.iq-tech-tile.is-disabled .iq-tile-count { display: none; }

.iq-chip-count {
   margin-left: 7px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10.5px;
   line-height: 1;
   color: var(--iq-ink4);
   font-variant-numeric: tabular-nums;
}
.iq-pk-chip.is-on .iq-chip-count { color: var(--iq-paper); opacity: .72; }

/* Sub-labels for the grouped stack chip runs (roles vs stacks/frameworks). */
.iq-pk-runlabel {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   letter-spacing: .09em;
   text-transform: uppercase;
   color: var(--iq-ink4);
   margin: 2px 0 8px;
}
.iq-pk-runlabel + .iq-chip-row { margin-bottom: 18px; }

/* Search miss -> the sitewide index, rather than a dead end. The picker only
   knows technologies and topics; /search also covers questions and sheets. */
.iq-pk-escape {
   margin-top: 22px;
   padding-top: 16px;
   border-top: 1px solid var(--iq-rule);
}
.iq-pk-escape a {
   font-size: 14px;
   color: var(--iq-accent, #E55A12);
   text-decoration: none;
   font-weight: 500;
}
.iq-pk-escape a:hover { text-decoration: underline; }
.iq-tech-tile:hover {
   border-color: var(--iq-ink4);
   background: var(--iq-paper);
}
.iq-tech-tile.is-active {
   background: var(--iq-dark);
   color: var(--iq-paper);
   border-color: var(--iq-dark);
}
.iq-tech-tile.is-active .iq-tech-initials,
.iq-tech-tile.is-active .iq-tech-icon {
   box-shadow: 0 0 0 1px rgba(255,255,255,0.12);
}
/* Brand badge. Shared geometry between the simple-icons SVG glyph and the
   letter fallback so the grid stays even regardless of which path renders.
   Background hex + foreground colour are set inline per-tile (brand hex for
   matched icons, hashed palette for the fallback; foreground flips dark on
   light brand hexes via the luminance check). */
.iq-tech-initials,
.iq-tech-icon {
   width: 32px;
   height: 32px;
   border-radius: 7px;
   display: inline-flex;
   align-items: center;
   justify-content: center;
   flex-shrink: 0;
}
.iq-tech-initials {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   font-weight: 400;
   letter-spacing: -0.01em;
   text-transform: uppercase;
   line-height: 1;
}
.iq-tech-icon svg {
   width: 18px;
   height: 18px;
   display: block;
}
/* Hand-drawn glyph marks inside the round cross-cutting badge. */
.iq-topic-badge svg {
   width: 23px;
   height: 23px;
   display: block;
}
/* Sprite host for the topic-glyph <symbol>s: present in the layout, never
   painted. Not display:none — that stops Safari resolving <use> into it. */
.iq-mark-sprite {
   position: absolute;
   width: 0;
   height: 0;
   overflow: hidden;
   pointer-events: none;
}

/* ---------- Sticky filter bar ---------- */
.iq-filterbar {
   position: sticky;
   top: 64px;
   z-index: 20;
   background: var(--iq-paper);
   border-bottom: 1px solid var(--iq-rule);
   margin-bottom: 18px;
}
.iq-filterbar-inner {
   display: flex;
   align-items: center;
   gap: 10px;
   padding: 10px 0;
   overflow-x: auto;
   scrollbar-width: none;
}
.iq-filterbar-inner::-webkit-scrollbar { display: none; }
.iq-filterbar-label {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   font-weight: 400;
   letter-spacing: 0.08em;
   text-transform: uppercase;
   color: var(--iq-ink3);
   white-space: nowrap;
}
.iq-diff-chip {
   display: inline-flex;
   align-items: center;
   gap: 7px;
   padding: 5px 12px;
   border-radius: 999px;
   border: 1px solid var(--iq-rule2);
   background: var(--iq-card);
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13.5px;
   font-weight: 500;
   color: var(--iq-ink2);
   text-decoration: none;
   transition: background-color .15s ease, color .15s ease, border-color .15s ease;
   white-space: nowrap;
   cursor: pointer;
}
.iq-diff-dot {
   width: 7px; height: 7px; border-radius: 999px;
   background: var(--iq-ink5);
   flex-shrink: 0;
}
/* Dots are always tinted in their difficulty color so the legend reads at a glance,
   even when no chip is active. The chip background/text only changes on hover/active. */
.iq-diff-chip.iq-diff-beginner     .iq-diff-dot { background: radial-gradient(circle at 35% 30%, #63C79A, var(--iq-greenDot) 70%); box-shadow: 0 0 5px rgba(46,158,107,.5); }
.iq-diff-chip.iq-diff-intermediate .iq-diff-dot { background: radial-gradient(circle at 35% 30%, #EDC55C, var(--iq-amberDot) 70%); box-shadow: 0 0 5px rgba(217,160,19,.5); }
.iq-diff-chip.iq-diff-expert       .iq-diff-dot { background: radial-gradient(circle at 35% 30%, #E07B62, var(--iq-roseDot) 70%); box-shadow: 0 0 5px rgba(196,68,46,.5); }
/* Hover previews the active tint — gives the user a clear sense of the affordance. */
.iq-diff-chip.iq-diff-beginner:hover     { background: var(--iq-greenS); color: var(--iq-green); border-color: transparent; }
.iq-diff-chip.iq-diff-intermediate:hover { background: var(--iq-amberS); color: var(--iq-amber); border-color: transparent; }
.iq-diff-chip.iq-diff-expert:hover       { background: var(--iq-roseS);  color: var(--iq-rose);  border-color: transparent; }
/* Active state — same hue, heavier text so it reads as locked-in. */
.iq-diff-chip.iq-diff-beginner.is-active     { background: var(--iq-greenS); color: var(--iq-green); border-color: transparent; font-weight: 600; }
.iq-diff-chip.iq-diff-intermediate.is-active { background: var(--iq-amberS); color: var(--iq-amber); border-color: transparent; font-weight: 600; }
.iq-diff-chip.iq-diff-expert.is-active       { background: var(--iq-roseS);  color: var(--iq-rose);  border-color: transparent; font-weight: 600; }

/* Reset: small ghost text-link so it doesn't read as a fourth pill / fourth
   selectable difficulty. Only appears when at least one chip is narrowing. */
.iq-diff-reset {
   margin-left: 6px;
   padding: 5px 4px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13px;
   font-weight: 500;
   color: var(--iq-ink3);
   text-decoration: none;
   border-bottom: 1px dashed transparent;
   transition: color .15s ease, border-color .15s ease;
   white-space: nowrap;
}
.iq-diff-reset:hover {
   color: var(--iq-ink);
   border-bottom-color: var(--iq-ink4);
}

/* ---------- Section header ---------- */
.iq-section-header {
   display: flex;
   align-items: baseline;
   justify-content: space-between;
   gap: 12px;
   margin: 24px 0 14px;
   flex-wrap: wrap;
}
/* The mode kicker takes the whole first line so the title/count row keeps its
   space-between layout. */
.iq-section-kicker { flex-basis: 100%; margin-bottom: 2px; }
.iq-section-title {
   font-family: 'Instrument Sans', system-ui, sans-serif;
   font-weight: 600;
   font-size: 26px;
   line-height: 1.1;
   letter-spacing: -0.035em;
   color: var(--iq-ink);
   margin: 0;
}
@media (max-width: 879px) {
   .iq-section-title { font-size: 22px; }
}
.iq-section-count {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 13px;
   font-weight: 400;
   color: var(--iq-ink3);
}

/* ---------- Question list ----------
   The drill list is an INDEX, not a stack of cards. 107 bordered, gapped,
   colour-tabbed cards spend chrome on every row equally, which is the same as
   spending it on none: nothing can stand out. So the resting state is a ruled
   field - hairline between rows, no border, no gap, no fill - and every scrap
   of weight is saved for state the reader created (hover, open, bookmarked).

   Difficulty is not painted per row. The hub serves questions ascending, so a
   left-edge tint repeated the same value 33 rows running; it now reads once per
   run from .iq-band, where the word is spelled out and works without colour. */
.iq-rows {
   border-top: 1px solid var(--iq-rule);
   margin-top: 4px;
}

/* Difficulty band header. Named, counted, and ruled to the right margin - the
   count is live because the chips/search filter client-side. */
.iq-band {
   display: flex;
   align-items: center;
   gap: 13px;
   padding: 26px 12px 10px 0;
}
.iq-band:first-child { padding-top: 16px; }
.iq-band-label {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 11.5px;
   font-weight: 700;
   letter-spacing: 0.115em;
   text-transform: uppercase;
   flex-shrink: 0;
}
.iq-band-rule {
   flex: 1;
   min-width: 16px;
   height: 1px;
   background: var(--iq-rule);
}
.iq-band-count {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   color: var(--iq-ink4);
   font-variant-numeric: tabular-nums;
   flex-shrink: 0;
}
/* The three colour moments on this page. Deep editorial tones, not the bright
   --*Dot values: this is tinted type, not a badge. */
.iq-band[data-difficulty="beginner"]     .iq-band-label { color: var(--iq-green); }
.iq-band[data-difficulty="intermediate"] .iq-band-label { color: var(--iq-amber); }
.iq-band[data-difficulty="advanced"]     .iq-band-label { color: var(--iq-amber); }
.iq-band[data-difficulty="expert"]       .iq-band-label { color: var(--iq-rose); }

/* ---------- Question rows ---------- */
.iq-row {
   position: relative;
   /* Reload-restore scrolls the reopened row into view (interview-questions.js
      init) - keep it clear of the sticky site header. */
   scroll-margin-top: 86px;
   border-bottom: 1px solid var(--iq-divider);
   transition: background-color .14s ease, box-shadow .2s ease, margin .2s ease;
}
.iq-row-header {
   /* No left padding: the folio gutter IS the left margin, so the title sits on
      the same axis whether the row is resting, hovered or open - opening a row
      must never shift the words the reader is already looking at. */
   display: grid;
   grid-template-columns: 44px minmax(0, 1fr) auto;
   column-gap: 14px;
   align-items: start;
   width: 100%;
   background: transparent;
   border: 0;
   border-radius: 10px;
   padding: 13px 12px 13px 0;
   text-align: left;
   cursor: pointer;
   color: inherit;
}
/* The header is a role=button with tabindex - it had no visible focus state. */
.iq-row-header:focus-visible {
   outline: 2px solid var(--iq-accent);
   outline-offset: -2px;
}
/* Folio. Right-aligned against the title axis (index convention, and the only
   alignment that survives the jump from 99 to 100), tabular so the column never
   jitters, and quiet enough to read as a reference mark rather than content. */
.iq-row-index {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12.5px;
   font-weight: 400;
   line-height: 23px;
   font-variant-numeric: tabular-nums;
   color: var(--iq-ink5);
   text-align: right;
   transition: color .14s ease;
}
.iq-row-main { min-width: 0; }
.iq-row-title {
   font-family: 'Instrument Sans', system-ui, sans-serif;
   font-weight: 600;
   font-size: 16.5px;
   line-height: 1.4;
   letter-spacing: -0.035em;
   color: var(--iq-ink);
   margin: 0;
   overflow: hidden;
   text-overflow: ellipsis;
   display: -webkit-box;
   -webkit-line-clamp: 2;
   -webkit-box-orient: vertical;
}
/* The rail is a fixed grid, not a flex row: with marks that come and go per
   row, flex packs them rightward and every mark lands at a different x on every
   row - which is what made the old rail read as clutter. Fixed slots mean the
   locks line up under the locks and the diagram marks under the diagram marks,
   so the rail becomes three readable columns instead of scattered chips.
   min-height pins it to the title's FIRST line, so a two-line title doesn't
   drag the marks down to a floating midpoint. */
.iq-row-side {
   display: grid;
   grid-template-columns: 13px 78px 14px 15px 16px;
   column-gap: 9px;
   align-items: center;
   justify-items: center;
   min-height: 23px;
}
.iq-row-side .iq-row-lock                              { grid-column: 1; }
.iq-row-side .iq-viz-chip                              { grid-column: 2; justify-self: start; }
.iq-row-side .iq-mastery-check,
.iq-row-side .iq-mastery-dot                           { grid-column: 3; }
.iq-row-side .iq-bm-btn                                { grid-column: 4; }
.iq-row-side .iq-row-chevron                           { grid-column: 5; }
.iq-row-chevron {
   color: var(--iq-ink5);
   transition: transform .2s ease, color .14s ease;
}

/* Hover: the row lifts to the card surface and its hairlines (its own, and the
   one the row above draws) get out of the way, so the wash reads as one clean
   block rather than a boxed cell. */
@media (hover: hover) {
   .iq-row:hover {
      background: var(--iq-card);
      border-radius: 10px;
      border-bottom-color: transparent;
   }
   .iq-row:has(+ .iq-row:hover) { border-bottom-color: transparent; }
   .iq-row:hover .iq-row-index   { color: var(--iq-ink3); }
   .iq-row:hover .iq-row-chevron { color: var(--iq-ink3); }
}

/* Open: NOW it earns a card. Detaching the read row from the field is the whole
   reason cards exist, and it only happens to one row at a time. */
.iq-row.is-expanded {
   background: var(--iq-card);
   border-radius: 14px;
   border-bottom-color: transparent;
   margin: 12px 0;
   box-shadow: 0 1px 2px rgba(35, 35, 32, .05), 0 22px 44px -30px rgba(35, 35, 32, .45);
}
.iq-row:has(+ .iq-row.is-expanded) { border-bottom-color: transparent; }
.iq-row.is-expanded .iq-row-index   { color: var(--iq-accent); }
.iq-row.is-expanded .iq-row-chevron { transform: rotate(180deg); color: var(--iq-ink3); }
/* Open, the panel below carries the real (actionable) Diagram chip - two marks
   reading "DIAGRAM" in one row is just noise. Faded, not removed, so the rail's
   columns hold their positions. */
.iq-row.is-expanded .iq-row-side .iq-viz-chip { opacity: 0; pointer-events: none; }
/* An open row is the row the reader is working in: its bookmark stays put
   instead of waiting on hover. */
.iq-row.is-expanded .iq-row-side .iq-bm-btn { opacity: 1; }

/* Row rail marks. The lock and the diagram mark fire on most rows of a premium
   topic, so neither may be a filled chip - they are set as small type and read
   by colour and shape instead of by a background. */
.iq-row-side .iq-viz-chip {
   padding: 0;
   gap: 4px;
   background: transparent;
   color: var(--iq-accentD);
   font-size: 10.5px;
   letter-spacing: 0.07em;
}
/* Bookmarks are a per-row control on a 107-row list: showing 107 of them at
   rest is noise. Revealed on hover (pointer devices only - a touch device
   never hovers, so it keeps them), on keyboard focus, and always once set. */
@media (hover: hover) and (min-width: 880px) {
   .iq-row-side .iq-bm-btn { opacity: 0; transition: opacity .14s ease; }
   .iq-row:hover .iq-row-side .iq-bm-btn,
   .iq-row-header:focus-visible .iq-row-side .iq-bm-btn,
   .iq-row-side .iq-bm-btn:focus-visible,
   .iq-row-side .iq-bm-btn.is-on { opacity: 1; }
}

/* Only the tweening goes: the flipped chevron is state, not decoration, so the
   open row still points its arrow the other way. */
@media (prefers-reduced-motion: reduce) {
   .iq-row,
   .iq-row-index,
   .iq-row-chevron,
   .iq-row-side .iq-bm-btn { transition: none; }
}

@media (max-width: 700px) {
   .iq-row-header { grid-template-columns: 30px minmax(0, 1fr) auto; column-gap: 11px; padding: 12px 6px 12px 0; }
   .iq-row-index  { font-size: 11.5px; }
   .iq-row-title  { font-size: 15.5px; -webkit-line-clamp: 3; }
   /* Reserved slots are a desktop scanning nicety: five of them would claim a
      quarter of a 390px screen and clip the question itself. Here the rail packs
      to what a row actually has, and the title takes back the difference. */
   .iq-row-side   { display: flex; gap: 11px; }
   .iq-band       { padding: 22px 6px 9px 0; }
}

/* difficulty pill (same colors as filter chip but always tinted) */
.iq-pill {
   display: inline-flex;
   align-items: center;
   gap: 6px;
   padding: 4px 10px;
   border-radius: 999px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 12.25px;
   font-weight: 700;
   letter-spacing: 0.05em;
   text-transform: uppercase;
   white-space: nowrap;
}
.iq-pill .iq-diff-dot { width: 7px; height: 7px; }
.iq-pill.iq-pill-beginner     { background: var(--iq-greenS); color: var(--iq-green); }
.iq-pill.iq-pill-beginner     .iq-diff-dot { background: radial-gradient(circle at 35% 30%, #63C79A, var(--iq-greenDot) 70%); box-shadow: 0 0 5px rgba(46,158,107,.5); }
.iq-pill.iq-pill-intermediate { background: var(--iq-amberS); color: var(--iq-amber); }
.iq-pill.iq-pill-intermediate .iq-diff-dot { background: radial-gradient(circle at 35% 30%, #EDC55C, var(--iq-amberDot) 70%); box-shadow: 0 0 5px rgba(217,160,19,.5); }
.iq-pill.iq-pill-advanced     { background: var(--iq-amberS); color: var(--iq-amber); }
.iq-pill.iq-pill-advanced     .iq-diff-dot { background: radial-gradient(circle at 35% 30%, #EDC55C, var(--iq-amberDot) 70%); box-shadow: 0 0 5px rgba(217,160,19,.5); }
.iq-pill.iq-pill-expert       { background: var(--iq-roseS);  color: var(--iq-rose); }
.iq-pill.iq-pill-expert       .iq-diff-dot { background: radial-gradient(circle at 35% 30%, #E07B62, var(--iq-roseDot) 70%); box-shadow: 0 0 5px rgba(196,68,46,.5); }

/* Pro chip */
/* "Diagram" chip: a hand-reviewed interactive figure exists on this question's
   Visualize tab. Server-rendered (unlike the Alpine mastery dot). This is the
   filled chip used on panels and the single-question page; the hub's list
   flattens it to plain type - see .iq-row-side .iq-viz-chip, which fires on
   most rows of a topic and so must not carry a fill. Icon-only under the 700px
   break to protect row width. */
.iq-viz-chip {
   display: inline-flex;
   align-items: center;
   gap: 5px;
   padding: 4px 9px;
   border-radius: 999px;
   background: var(--iq-accentS);
   color: var(--iq-accentD);
   font-family: 'Instrument Sans', sans-serif;
   font-size: 11px;
   font-weight: 700;
   letter-spacing: 0.05em;
   text-transform: uppercase;
   white-space: nowrap;
}
@media (max-width: 700px) {
   .iq-viz-chip { padding: 4px 6px; }
   .iq-viz-chip .iq-viz-chip-label { display: none; }
}
/* Interactive variant of the same chip: the explain bar's state-aware
   "Diagram" affordance (anchor on the single page, inline-reveal button on
   hub rows). Same identity + type as the row-header chip; interaction
   states follow the .iq-steer-chip idiom (accent tokens only). */
a.iq-viz-chip.iq-viz-chip-act,
button.iq-viz-chip.iq-viz-chip-act {
   border: 1px solid transparent;
   cursor: pointer;
   text-decoration: none;
   transition: border-color .15s ease, background .15s ease;
}
a.iq-viz-chip.iq-viz-chip-act:hover,
button.iq-viz-chip.iq-viz-chip-act:hover:not(:disabled) {
   border-color: var(--iq-accent);
   text-decoration: none;
}
button.iq-viz-chip.iq-viz-chip-act:disabled { opacity: .4; cursor: default; }
a.iq-viz-chip.iq-viz-chip-act:focus-visible,
button.iq-viz-chip.iq-viz-chip-act:focus-visible { outline: 2px solid var(--iq-accent); outline-offset: 1px; }
button.iq-viz-chip.iq-viz-chip-act.is-on { border-color: var(--iq-accent); }

.iq-pro-chip {
   display: inline-flex;
   align-items: center;
   gap: 4px;
   padding: 3px 8px;
   border-radius: 999px;
   background: var(--iq-accentS);
   color: var(--iq-accentD);
   font-family: 'Instrument Sans', sans-serif;
   font-size: 11.5px;
   font-weight: 700;
   letter-spacing: 0.06em;
   text-transform: uppercase;
   white-space: nowrap;
}

/* Expanded body. Indented to the title axis (44px gutter + 14px gap) so the
   answer hangs off the question instead of restarting at the card edge - which
   also starts the divider at the text axis rather than ruling the whole card. */
.iq-row-body {
   margin-left: 58px;
   padding: 15px 14px 20px 0;
   border-top: 1px solid var(--iq-divider);
}
@media (max-width: 700px) {
   .iq-row-body { margin-left: 0; padding: 14px 12px 18px 12px; }
}

/* Shared Markdown typography for curated answers and generated explanations.
   Tailwind resets all list markers and element margins, so these rules must be
   explicit. Keeping both surfaces together prevents the topic accordion and
   single-question reader from drifting apart. */
.iq-prose,
.iq-ai-result {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 16px;
   line-height: 1.7;
   color: var(--iq-ink2);
}
.iq-prose > *:first-child,
.iq-ai-result > *:first-child { margin-top: 0; }
.iq-prose > *:last-child,
.iq-ai-result > *:last-child { margin-bottom: 0; }
.iq-prose h1, .iq-prose h2, .iq-prose h3,
.iq-ai-result h1, .iq-ai-result h2, .iq-ai-result h3 {
   font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em;
   font-weight: 600;
   color: var(--iq-ink);
   line-height: 1.3;
}
.iq-prose h1, .iq-ai-result h1 { font-size: 21px; margin: 20px 0 8px; }
.iq-prose h2, .iq-ai-result h2 { font-size: 18.5px; margin: 18px 0 7px; }
.iq-prose h3, .iq-ai-result h3 { font-size: 16.5px; margin: 16px 0 6px; }
.iq-prose h4, .iq-prose h5, .iq-prose h6,
.iq-ai-result h4, .iq-ai-result h5, .iq-ai-result h6 {
   font-family: 'Instrument Sans', sans-serif;
   font-weight: 600;
   color: var(--iq-ink);
   line-height: 1.35;
}
.iq-prose h4,
.iq-ai-result h4 {
   font-size: 15px;
   margin: 14px 0 5px;
}
.iq-prose h5,
.iq-ai-result h5 { font-size: 14.5px; margin: 12px 0 5px; }
.iq-prose h6,
.iq-ai-result h6 { font-size: 14px; margin: 12px 0 5px; }
.iq-prose p,
.iq-ai-result p { margin: 0 0 12px; }
.iq-prose ul, .iq-ai-result ul,
.iq-prose ol, .iq-ai-result ol {
   margin: 0 0 12px;
   padding-left: 22px;
}
.iq-prose ul, .iq-ai-result ul { list-style: disc; }
.iq-prose ol, .iq-ai-result ol { list-style: decimal; }
/* Visual explanations contain semantic lists with their own layout. Keep the
   prose marker reset from adding bullets, numbering, or left indentation to
   tree, state, legend, and set-diagram components. */
.iq-ai-result .iqv ul,
.iq-ai-result .iqv ol {
   list-style: none;
   padding-left: 0;
   margin-bottom: 0;
}
.iq-ai-result .iqv li { margin-bottom: 0; }
.iq-ai-result .iqv .iqv-strans { margin-top: 12px; }
.iq-prose li,
.iq-ai-result li { margin: 0 0 5px; }
.iq-prose li::marker,
.iq-ai-result li::marker { color: var(--iq-ink4); }
.iq-prose strong,
.iq-ai-result strong { color: var(--iq-ink); font-weight: 600; }
.iq-prose em,
.iq-ai-result em { font-style: italic; }
.iq-prose a,
.iq-ai-result a { color: var(--iq-accentD); text-decoration: underline; text-underline-offset: 2px; }
.iq-prose hr,
.iq-ai-result hr { border: 0; border-top: 1px solid var(--iq-divider); margin: 16px 0; }
.iq-prose blockquote,
.iq-ai-result blockquote {
   margin: 14px 0;
   padding: 10px 16px;
   border-left: 3px solid var(--iq-accent);
   background: var(--iq-paper);
   border-radius: 0 8px 8px 0;
   color: var(--iq-ink);
}
.iq-prose blockquote p,
.iq-ai-result blockquote p { margin: 0 0 10px; }
.iq-prose blockquote p:last-child,
.iq-ai-result blockquote p:last-child { margin-bottom: 0; }
.iq-prose code,
.iq-ai-result code {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 14px;
   background: var(--iq-paper);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 4px;
   padding: 1px 5px;
   color: var(--iq-ink);
}
.iq-prose pre,
.iq-ai-result pre {
   background: #2A2A26;
   color: #E6E5E0;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 14px;
   line-height: 1.55;
   padding: 14px 16px;
   border-radius: 10px;
   overflow-x: auto;
   margin: 12px 0;
   border: 1px solid #3B3B36;
}
.iq-prose pre code,
.iq-ai-result pre code {
   background: transparent;
   border: 0;
   padding: 0;
   color: inherit;
   font-size: inherit;
}

.iq-row-actions {
   display: flex;
   gap: 8px;
   margin-top: 16px;
   flex-wrap: wrap;
}
.iq-action-btn {
   display: inline-flex;
   align-items: center;
   gap: 6px;
   padding: 7px 12px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 8px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13.5px;
   font-weight: 600;
   color: var(--iq-ink2);
   cursor: pointer;
   text-decoration: none;
   transition: all .15s ease;
}
.iq-action-btn:hover {
   border-color: var(--iq-ink4);
   background: var(--iq-paper);
   color: var(--iq-ink);
}
.iq-action-btn .iq-action-icon { color: var(--iq-accent); }
.iq-action-btn .iq-action-suffix {
   margin-left: 6px;
   padding-left: 8px;
   border-left: 1px solid var(--iq-cardEdge);
   color: var(--iq-ink4);
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   font-weight: 400;
}

/* ---------- Premium teaser (inside expanded premium row) ---------- */
.iq-premium-teaser {
   position: relative;
}
.iq-premium-blur {
   position: relative;
   color: var(--iq-ink3);
   filter: blur(3.5px);
   user-select: none;
   pointer-events: none;
   margin-bottom: 0;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 16px;
   line-height: 1.7;
}
.iq-premium-blur::after {
   content: '';
   position: absolute;
   inset: 0;
   background: linear-gradient(180deg, transparent 0%, var(--iq-card) 88%);
   pointer-events: none;
}
.iq-premium-unlock {
   margin-top: -4px;
   padding: 18px;
   background: var(--iq-paper);
   border: 1px dashed var(--iq-accentE);
   border-radius: 12px;
   display: flex;
   align-items: flex-start;
   gap: 14px;
   flex-wrap: wrap;
}
.iq-premium-lock {
   width: 32px; height: 32px;
   border-radius: 8px;
   background: var(--iq-accentS);
   color: var(--iq-accentD);
   display: flex; align-items: center; justify-content: center;
   flex-shrink: 0;
}
.iq-premium-unlock-text {
   flex: 1;
   min-width: 200px;
}
.iq-premium-unlock-title {
   font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em;
   font-weight: 600;
   font-size: 18px;
   color: var(--iq-ink);
   margin: 0 0 4px;
}
.iq-premium-unlock-sub {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 14px;
   color: var(--iq-ink3);
   margin: 0;
}
.iq-premium-cta-row {
   display: flex;
   gap: 8px;
   flex-wrap: wrap;
   width: 100%;
   margin-top: 4px;
}
@media (max-width: 480px) {
   .iq-premium-cta-row { flex-direction: column; }
   .iq-premium-cta-row .iq-btn { justify-content: center; text-align: center; }
}
.iq-btn {
   display: inline-flex;
   align-items: center;
   gap: 6px;
   padding: 9px 14px;
   border-radius: 8px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 14px;
   font-weight: 600;
   text-decoration: none;
   border: 1px solid transparent;
   cursor: pointer;
   transition: all .15s ease;
}
.iq-btn-dark {
   background: var(--iq-dark);
   color: var(--iq-paper);
}
.iq-btn-dark:hover { background: var(--iq-darkD); }
.iq-btn-accent {
   background: linear-gradient(180deg, #F06A24, var(--iq-accent));
   color: #FFFFFF;
   box-shadow: 0 1px 0 rgba(255,255,255,.35) inset, 0 2px 5px -1px rgba(194,74,11,.6);
}
.iq-btn-accent:hover { background: linear-gradient(180deg, #E8611C, var(--iq-accentD)); }
.iq-btn-accent:active { transform: translateY(1px); }
.iq-btn-ghost {
   background: transparent;
   color: var(--iq-ink2);
   border-color: var(--iq-cardEdge);
}
.iq-btn-ghost:hover { background: var(--iq-paper); border-color: var(--iq-ink4); }

/* ---------- Pagination ---------- */
.iq-pagination {
   display: flex;
   justify-content: center;
   gap: 4px;
   margin: 28px 0 8px;
   flex-wrap: wrap;
}
.iq-pagination a, .iq-pagination span {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   min-width: 36px;
   height: 36px;
   padding: 0 10px;
   border-radius: 8px;
   border: 1px solid var(--iq-cardEdge);
   background: var(--iq-card);
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 13.5px;
   font-weight: 400;
   color: var(--iq-ink2);
   text-decoration: none;
   transition: all .15s ease;
}
.iq-pagination a:hover {
   border-color: var(--iq-accent);
   color: var(--iq-accent);
}
.iq-pagination .iq-pagination-active {
   background: var(--iq-accent);
   color: #F8F7F4;
   border-color: var(--iq-accent);
}
.iq-pagination .iq-pagination-disabled {
   color: var(--iq-ink5);
   cursor: not-allowed;
   background: var(--iq-paper);
}
.iq-pagination .iq-pagination-ellipsis {
   border: 0; background: transparent;
}
.iq-pagination-info {
   text-align: center;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12.5px;
   color: var(--iq-ink3);
   margin-bottom: 24px;
}

/* ---------- Bottom premium card (dark with radial glow) ---------- */
.iq-premium-card {
   position: relative;
   background: linear-gradient(180deg, #2E2E2A, var(--iq-dark));
   color: var(--iq-paper);
   border: 1px solid var(--iq-darkD);
   border-radius: 16px;
   padding: 28px;
   margin: 32px 0;
   overflow: hidden;
   isolation: isolate;
   box-shadow: 0 1px 0 rgba(255,255,255,.12) inset, 0 18px 40px -22px rgba(35,35,32,.7); /* black module */
}
.iq-premium-card::before {
   content: '';
   position: absolute;
   top: 26px;
   right: 28px;
   width: 110px; height: 18px; border-radius: 3px;
   background: repeating-linear-gradient(90deg, #3A3A34 0 2px, transparent 2px 7px); /* grille */
   z-index: -1;
}
.iq-premium-card-inner {
   display: grid;
   grid-template-columns: 1fr;
   gap: 22px;
}
@media (min-width: 880px) {
   .iq-premium-card-inner { grid-template-columns: 1fr auto; align-items: end; }
}
.iq-premium-eyebrow {
   display: inline-flex;
   align-items: center;
   gap: 6px;
   background: rgba(229, 90, 18, 0.18);
   color: #FFB783;
   padding: 5px 11px;
   border-radius: 999px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 12px;
   font-weight: 700;
   letter-spacing: 0.06em;
   text-transform: uppercase;
   margin-bottom: 12px;
}
.iq-premium-headline {
   font-family: 'Instrument Sans', system-ui, sans-serif;
   font-weight: 700;
   font-size: 28px;
   line-height: 1.15;
   letter-spacing: -0.035em;
   color: var(--iq-paper);
   margin: 0 0 10px;
}
.iq-premium-headline .iq-premium-num {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   color: var(--iq-accent);
   font-weight: 400;
}
.iq-premium-sub {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 15px;
   color: rgba(233,232,227, 0.7);
   margin: 0 0 18px;
   max-width: 60ch;
}
.iq-premium-checks {
   display: grid;
   grid-template-columns: repeat(2, minmax(0, 1fr));
   gap: 8px 18px;
   list-style: none;
   padding: 0;
   margin: 0;
}
@media (min-width: 880px) {
   .iq-premium-checks { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.iq-premium-checks li {
   display: flex;
   align-items: center;
   gap: 8px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 14px;
   color: rgba(233,232,227, 0.85);
}
.iq-premium-checks svg { color: var(--iq-accent); flex-shrink: 0; }
.iq-premium-cta {
   display: flex;
   flex-direction: column;
   align-items: flex-start;
   gap: 8px;
}
@media (min-width: 880px) {
   .iq-premium-cta { align-items: flex-end; }
}
.iq-premium-cta-link {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13px;
   color: rgba(233,232,227, 0.6);
   text-decoration: none;
}
.iq-premium-cta-link:hover { color: var(--iq-paper); }

/* ---------- AI Modal ---------- */
.iq-ai-backdrop {
   position: fixed;
   inset: 0;
   background: rgba(35,35,32, 0.55);
   backdrop-filter: blur(6px);
   -webkit-backdrop-filter: blur(6px);
   z-index: 100;
   display: flex;
   align-items: center;
   justify-content: center;
   padding: 16px;
}
.iq-ai-modal {
   background: var(--iq-card);
   border-radius: 16px;
   max-width: 540px;
   width: 100%;
   max-height: 90vh;
   overflow: hidden;
   display: flex;
   flex-direction: column;
   box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.4);
}
.iq-ai-header {
   padding: 22px 22px 14px;
   display: flex;
   align-items: flex-start;
   gap: 12px;
   border-bottom: 1px solid var(--iq-divider);
}
.iq-ai-header-icon {
   width: 36px; height: 36px;
   border-radius: 10px;
   background: var(--iq-accentS);
   color: var(--iq-accentD);
   display: flex; align-items: center; justify-content: center;
   flex-shrink: 0;
}
.iq-ai-header-text { flex: 1; }
.iq-ai-header-title {
   font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em;
   font-weight: 600;
   font-size: 19px;
   color: var(--iq-ink);
   margin: 0 0 2px;
}
.iq-ai-header-sub {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13px;
   color: var(--iq-ink3);
   margin: 0;
}
.iq-ai-close {
   border: 0;
   background: transparent;
   color: var(--iq-ink3);
   cursor: pointer;
   padding: 6px;
   border-radius: 8px;
   transition: all .15s ease;
}
.iq-ai-close:hover { background: var(--iq-paper); color: var(--iq-ink); }
.iq-ai-body {
   padding: 18px 22px;
   overflow-y: auto;
   flex: 1;
}
.iq-ai-eyebrow {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   font-weight: 400;
   letter-spacing: 0.1em;
   text-transform: uppercase;
   color: var(--iq-ink3);
   margin: 12px 0 6px;
}
.iq-ai-eyebrow:first-child { margin-top: 0; }
.iq-ai-question {
   font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em;
   font-weight: 600;
   font-size: 18px;
   line-height: 1.35;
   color: var(--iq-ink);
   margin: 0 0 4px;
}
.iq-ai-segmented {
   display: inline-flex;
   border: 1px solid var(--iq-cardEdge);
   border-radius: 8px;
   overflow: hidden;
   background: var(--iq-paper);
   padding: 3px;
   gap: 2px;
   flex-wrap: wrap;
}
.iq-ai-segmented-btn {
   border: 0;
   background: transparent;
   padding: 6px 12px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13.5px;
   font-weight: 500;
   color: var(--iq-ink3);
   cursor: pointer;
   border-radius: 6px;
   transition: all .15s ease;
}
.iq-ai-segmented-btn:hover { color: var(--iq-ink); }
.iq-ai-segmented-btn.is-selected {
   background: var(--iq-card);
   color: var(--iq-ink);
   font-weight: 600;
   box-shadow: 0 1px 2px rgba(0,0,0,0.06);
}
.iq-ai-footer {
   padding: 14px 22px;
   background: var(--iq-paper);
   border-top: 1px solid var(--iq-divider);
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 12px;
}
.iq-ai-credits {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 13px;
   color: var(--iq-ink3);
}
/* Markdown tables in answers & AI explanations (answer HTML is stored
   pre-rendered, so tables can't be wrapped server-side) */
.iq-prose table,
.iq-ai-result table {
   width: 100%;
   border-collapse: collapse;
   margin: 0 0 14px;
   font-size: 14.5px;
}
.iq-prose th, .iq-prose td,
.iq-ai-result th, .iq-ai-result td {
   border-bottom: 1px solid var(--iq-divider);
   padding: 8px 10px;
   text-align: left;
   vertical-align: top;
}
.iq-prose th, .iq-ai-result th {
   color: var(--iq-ink);
   font-weight: 600;
   font-size: 13.5px;
}
@media (max-width: 879px) {
   .iq-prose table,
   .iq-ai-result table {
      display: block;
      max-width: 100%;
      overflow-x: auto;
      -webkit-overflow-scrolling: touch;
   }
}
.iq-ai-loading {
   display: flex;
   align-items: center;
   gap: 10px;
   color: var(--iq-ink3);
   font-family: 'Instrument Sans', sans-serif;
   font-size: 14px;
   padding: 12px 0;
}
.iq-ai-spinner {
   width: 18px; height: 18px;
   border: 2px solid var(--iq-cardEdge);
   border-top-color: var(--iq-accent);
   border-radius: 50%;
   animation: iqSpin .9s linear infinite;
}
@keyframes iqSpin { to { transform: rotate(360deg); } }

/* ---------- Inline "Re-explain at your level" control ---------- */
.iq-explain-bar {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 14px;
   flex-wrap: wrap;
   padding-bottom: 16px;
   margin-bottom: 18px;
   border-bottom: 1px solid var(--iq-divider);
}
.iq-explain-label {
   display: inline-flex;
   align-items: center;
   gap: 7px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   font-weight: 400;
   letter-spacing: 0.1em;
   text-transform: uppercase;
   color: var(--iq-ink3);
}
.iq-explain-spark { color: var(--iq-accent); }
.iq-explain-segmented { flex-wrap: wrap; }
.iq-explain-segmented .iq-ai-segmented-btn {
   display: inline-flex;
   align-items: center;
   gap: 6px;
}
.iq-explain-chip {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10.5px;
   font-weight: 400;
   letter-spacing: 0.04em;
   padding: 1px 5px;
   border-radius: 5px;
   text-transform: uppercase;
}
.iq-explain-chip.is-free { background: var(--iq-greenS); color: var(--iq-green); }
.iq-explain-chip.is-cost { background: var(--iq-accentS); color: var(--iq-accentD); }

.iq-explain-swap { margin-top: 2px; }
.iq-explain-error {
   margin-top: 6px;
   padding: 12px 14px;
   background: var(--iq-roseS);
   color: var(--iq-rose);
   border-radius: 8px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 14px;
}
.iq-explain-pending {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 16px;
   flex-wrap: wrap;
   padding: 18px 20px;
   background: var(--iq-paper);
   border: 1px dashed var(--iq-cardEdge);
   border-radius: 12px;
}
.iq-explain-pending-text {
   margin: 0;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 14.5px;
   line-height: 1.5;
   color: var(--iq-ink2);
}
.iq-explain-pending-text strong { color: var(--iq-ink); font-weight: 600; }
.iq-explain-foot {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 12px;
   flex-wrap: wrap;
   margin-top: 16px;
   padding-top: 14px;
   border-top: 1px solid var(--iq-divider);
}
.iq-explain-foot-note {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13px;
   color: var(--iq-ink4);
}
.iq-explain-link {
   border: 0;
   background: none;
   padding: 0;
   font: inherit;
   color: var(--iq-accentD);
   cursor: pointer;
   text-decoration: underline;
   text-underline-offset: 2px;
}
.iq-explain-link:hover { color: var(--iq-accent); }

/* Steer chips — fixed regeneration directions under the visual footer */
.iq-explain-steer {
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   gap: 8px;
   margin-top: 10px;
}
.iq-explain-steer-label {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11px;
   color: var(--iq-ink4);
}
.iq-steer-chip {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 12.5px;
   font-weight: 600;
   color: var(--iq-ink);
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 999px;
   padding: 5px 13px;
   cursor: pointer;
   transition: border-color .15s ease, color .15s ease;
}
.iq-steer-chip:hover:not(:disabled) { border-color: var(--iq-accent); color: var(--iq-accentD); }
.iq-steer-chip:disabled { opacity: .4; cursor: default; }
.iq-steer-chip:focus-visible { outline: 2px solid var(--iq-accent); outline-offset: 1px; }
.iq-steer-chip.is-selected { border-color: var(--iq-accent); color: var(--iq-accentD); }
/* The "none fits" verdict's quoted reason */
.iq-explain-reason { font-style: italic; color: var(--iq-ink3); }
/* Curated demand whisper (+ admin create/review entry) — one quiet footer
   line; type comes entirely from .iq-explain-foot-note / .iq-explain-link. */
.iq-whisper { margin-top: 8px; }
.iq-whisper-ok { color: var(--iq-green); }

/* Report-an-issue row — end of the explain panel, any aspect */
.iq-report {
   margin-top: 12px;
   padding-top: 8px;
   border-top: 1px dashed var(--iq-cardEdge);
}
.iq-report-note,
.iq-visual-report-note {
   display: inline-flex;
   flex-wrap: wrap;
   align-items: center;
   gap: 8px;
   margin-top: 8px;
}
.iq-report-note { display: flex; }
/* The figure-local report controls (iq-visual-section) toggle via the
   `hidden` attribute — plain DOM, no Alpine. An author display rule beats
   the UA's [hidden]{display:none}, so restate it or the note input and Send
   render permanently under every figure. */
.iq-visual-report-note[hidden],
.iq-visual-report-chips[hidden] { display: none !important; }
.iq-report-note-input {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 12.5px;
   color: var(--iq-ink);
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 999px;
   padding: 5px 13px;
   min-width: 220px;
   flex: 1 1 220px;
   max-width: 420px;
}
.iq-report-note-input:focus-visible { outline: 2px solid var(--iq-accent); outline-offset: 1px; }

/* Second angle (visual_alt) — below the primary on-page figure */
.iq-visual-alt { margin-top: 18px; }
.iq-visual-alt-note {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   color: var(--iq-ink4);
   margin: 10px 0 0;
}
.iq-visual-alt-cta {
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   gap: 12px;
   margin-top: 12px;
}
.iq-visual-alt-hint {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13px;
   color: var(--iq-ink4);
}
.visual-detail-alt { margin-top: 26px; }

/* ---------- Question detail page ---------- */
.iq-detail-meta {
   display: flex;
   align-items: center;
   gap: 8px;
   margin: 4px 0 10px;
   flex-wrap: wrap;
}
/* Save + Share/Copy-link chips in the hero meta row */
.iq-detail-actions { display: inline-flex; align-items: center; gap: 6px; }
.iq-action-chip {
   display: inline-flex;
   align-items: center;
   gap: 5px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 12.5px;
   font-weight: 600;
   color: var(--iq-ink2);
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 999px;
   padding: 4px 12px;
   cursor: pointer;
   transition: border-color .15s ease, color .15s ease;
}
.iq-action-chip:hover { border-color: var(--iq-accent); color: var(--iq-accentD); }
.iq-action-chip:focus-visible { outline: 2px solid var(--iq-accent); outline-offset: 1px; }
.iq-action-chip.is-on { border-color: var(--iq-accent); color: var(--iq-accentD); }
.iq-detail-num {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12.5px;
   font-weight: 400;
   letter-spacing: 0.08em;
   color: var(--iq-ink4);
   text-transform: uppercase;
}
.iq-detail-title {
   font-family: 'Instrument Sans', system-ui, sans-serif;
   font-weight: 700;
   font-size: 36px;
   line-height: 1.15;
   letter-spacing: -0.035em;
   color: var(--iq-ink);
   margin: 6px 0 18px;
   max-width: 28ch;
}
@media (max-width: 879px) {
   .iq-detail-title { font-size: 28px; }
}
.iq-detail-answer {
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 14px;
   padding: 26px 28px;
   margin-bottom: 24px;
}
@media (max-width: 879px) {
   .iq-detail-answer { padding: 20px 18px; }
}
.iq-detail-nav {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 10px;
   margin: 24px 0;
}
.iq-detail-nav-link {
   display: flex;
   flex-direction: column;
   gap: 4px;
   padding: 14px 16px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 10px;
   text-decoration: none;
   color: var(--iq-ink2);
   transition: all .15s ease;
}
.iq-detail-nav-link:hover { border-color: var(--iq-ink4); }
.iq-detail-nav-link.iq-detail-nav-disabled { opacity: 0.4; pointer-events: none; }
.iq-detail-nav-link.iq-detail-nav-next { text-align: right; }
/* Compact return-to-topic link on the single-question page (sits where the
   browse rail does on the hub pages). */
.iq-detail-topic-return {
   display: inline-flex;
   align-items: center;
   gap: 6px;
   margin: 0 0 18px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   font-weight: 400;
   letter-spacing: 0.08em;
   text-transform: uppercase;
   color: var(--iq-ink4);
   text-decoration: none;
}
.iq-detail-topic-return:hover { color: var(--iq-accent); }

.iq-detail-nav-eyebrow {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   font-weight: 400;
   letter-spacing: 0.08em;
   text-transform: uppercase;
   color: var(--iq-ink4);
}
/* Premium-sibling lock on the prev/next cards — the hero's Pro chip, scaled
   down to sit inline with the eyebrow text. */
.iq-detail-nav-pro {
   font-size: 10px;
   padding: 2px 7px;
   gap: 3px;
   vertical-align: text-bottom;
}
.iq-detail-nav-title {
   font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em;
   font-weight: 600;
   font-size: 15.5px;
   color: var(--iq-ink);
   line-height: 1.35;
   display: -webkit-box;
   -webkit-line-clamp: 2;
   -webkit-box-orient: vertical;
   overflow: hidden;
}

/* ---------- Empty state (category landing) ---------- */
.iq-empty {
   background: var(--iq-card);
   border: 1px dashed var(--iq-cardEdge);
   border-radius: 14px;
   padding: 38px 28px;
   text-align: center;
   color: var(--iq-ink3);
   font-family: 'Instrument Sans', sans-serif;
   font-size: 15px;
   margin: 24px 0;
}
.iq-empty-title {
   font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em;
   font-weight: 600;
   font-size: 20px;
   color: var(--iq-ink);
   margin: 0 0 6px;
}

/* ---------- Layout container ---------- */
.iq-page {
   max-width: 1280px;
   margin: 0 auto;
   padding: 0 28px;
}
@media (max-width: 879px) {
   .iq-page { padding: 0 16px; }
}

/* ============================================================================
   v4 SUBJECT HUB — picker, sticky subject nav, adaptive tabs, tab panels.
   Reuses the v2 tokens + .iq-row / .iq-pill / .iq-tech-tile / .iq-btn classes.
   ============================================================================ */

/* ---------- Picker card ---------- */
.iq-picker {
   background: var(--iq-card);
   border: 1px solid var(--iq-rule);
   border-radius: 16px;
   overflow: hidden;
   box-shadow: 0 24px 48px -32px rgba(35,35,32, .32);
   margin-top: 22px;
}
/* Search sits on its own full-width row ABOVE the lens segment. It is the only
   control that crosses every lens and the fastest path for anyone who already
   knows what they want, so it leads instead of hiding right-aligned behind a
   spacer. */
.iq-picker-searchrow {
   padding: 16px 26px 0;
   background: var(--iq-card);
}
.iq-picker-lensrow {
   display: flex;
   align-items: center;
   gap: 12px;
   flex-wrap: wrap;
   padding: 14px 26px 16px;
   border-bottom: 1px solid var(--iq-rule);
   background: var(--iq-card);
}
.iq-picker-spacer { flex: 1; min-width: 12px; }
.iq-lens-seg {
   display: inline-flex;
   gap: 3px;
   padding: 3px;
   border-radius: 11px;
   background: var(--iq-paper2);
   border: 1px solid var(--iq-rule);
}
.iq-lens-btn {
   appearance: none;
   border: none;
   cursor: pointer;
   padding: 7px 16px;
   border-radius: 8px;
   font-size: 14px;
   font-weight: 500;
   color: var(--iq-ink3);
   background: transparent;
   transition: all .15s ease;
}
.iq-lens-btn.is-on {
   background: var(--iq-card);
   color: var(--iq-ink);
   font-weight: 600;
   box-shadow: 0 1px 3px rgba(35,35,32, .12);
}
.iq-picker-search {
   display: flex;
   align-items: center;
   gap: 10px;
   padding: 0 14px;
   height: 44px;
   border-radius: 10px;
   background: var(--iq-paper2);
   border: 1px solid var(--iq-cardEdge);
   width: 100%;
   color: var(--iq-ink3);
   transition: border-color .15s ease, background .15s ease;
}
.iq-picker-search:focus-within {
   border-color: var(--iq-ink4);
   background: var(--iq-paper);
}
.iq-picker-search input {
   appearance: none;
   border: none;
   background: transparent;
   outline: none;
   flex: 1;
   min-width: 0;
   font-size: 14px;
   color: var(--iq-ink);
   font-family: 'Instrument Sans', sans-serif;
}
.iq-picker-search-clear {
   appearance: none;
   border: none;
   background: transparent;
   cursor: pointer;
   color: var(--iq-ink4);
   display: grid;
   place-items: center;
   padding: 0;
}
.iq-picker-body { padding: 24px 26px 30px; }
@media (max-width: 879px) {
   .iq-picker-searchrow { padding: 14px 16px 0; }
   .iq-picker-lensrow { padding: 12px 16px 14px; }
   .iq-picker-body { padding: 18px 16px 24px; }
   /* Lens buttons split the row evenly rather than crowding one line. */
   .iq-lens-seg { width: 100%; }
   .iq-lens-btn { flex: 1; padding: 7px 10px; text-align: center; }
}

/* ---------- Picker labels, chips, grids ---------- */
.iq-pk-label {
   display: flex;
   align-items: center;
   gap: 10px;
   margin-bottom: 14px;
}
.iq-pk-label > span:first-child,
.iq-pk-label-right {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   font-weight: 400;
   letter-spacing: .14em;
   text-transform: uppercase;
   color: var(--iq-ink4);
}
.iq-pk-label-right { margin-left: auto; }
.iq-chip-row {
   display: flex;
   flex-wrap: wrap;
   gap: 7px;
   margin-bottom: 16px;
}
.iq-pk-chip {
   appearance: none;
   cursor: pointer;
   display: inline-flex;
   align-items: center;
   gap: 8px;
   padding: 10px 18px;
   border-radius: 999px;
   font-size: 15px;
   font-weight: 500;
   color: var(--iq-ink);
   background: var(--iq-paper2);
   border: 1.5px solid transparent;
   white-space: nowrap;
   transition: background .12s ease, color .12s ease;
}
.iq-pk-chip.is-on {
   background: var(--iq-dark);
   color: var(--iq-paper);
   font-weight: 600;
   border-color: var(--iq-dark);
}
.iq-tile-grid {
   display: grid;
   /* Widened from 196px when tiles gained a question count: at 196px the label
      column was ~120px, so "Fine-Tuning & Model Customization" clipped
      mid-word. This yields 4 columns where it used to fit 5, which costs no
      extra rows at typical category sizes. */
   grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
   gap: 10px;
}
.iq-tile-grid-topic { grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); }
@media (max-width: 879px) {
   .iq-tile-grid, .iq-tile-grid-topic { grid-template-columns: 1fr; }
}
.iq-pk-divider {
   margin: 30px 0;
   border: none;
   border-top: 1px dashed var(--iq-rule2);
}
.iq-pk-empty {
   font-size: 14.5px;
   color: var(--iq-ink4);
   padding: 6px 0;
}

/* Picker tech tiles: larger than the rail variant they share a class with. */
.iq-picker .iq-tech-tile {
   padding: 14px 16px;
   border-radius: 14px;
   border-width: 1.5px;
   font-size: 17px;
   font-weight: 600;
   min-height: auto;
}
.iq-picker .iq-tech-tile.is-disabled {
   opacity: .55;
   cursor: default;
}
.iq-picker .iq-tech-initials,
.iq-picker .iq-tech-icon {
   width: 44px;
   height: 44px;
   border-radius: 11px;
}
.iq-picker .iq-tech-icon svg { width: 22px; height: 22px; }

/* Circle-badge topic tiles (cross-cutting concepts) */
.iq-topic-tile {
   display: flex;
   align-items: center;
   gap: 14px;
   padding: 14px 16px;
   border-radius: 14px;
   border: 1.5px solid var(--iq-cardEdge);
   background: var(--iq-card);
   color: var(--iq-ink);
   text-decoration: none;
   transition: border-color .15s ease, box-shadow .15s ease, transform .1s ease;
}
.iq-topic-tile:hover {
   border-color: var(--iq-rule2);
   box-shadow: 0 6px 18px -10px rgba(35,35,32, .35);
   transform: translateY(-1px);
}
.iq-topic-badge {
   width: 44px;
   height: 44px;
   border-radius: 999px;
   color: #F8F7F4;
   display: grid;
   place-items: center;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 14px;
   font-weight: 400;
   flex-shrink: 0;
}
/* flex:1 so a trailing .iq-tile-count is pushed to the right edge. */
.iq-topic-main { min-width: 0; flex: 1; }
.iq-topic-label {
   display: block;
   font-size: 16.5px;
   font-weight: 600;
   letter-spacing: -0.01em;
   line-height: 1.2;
}
.iq-topic-parent {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11px;
   color: var(--iq-ink4);
}

/* ---------- Cross-cutting block ---------- */
.iq-cc-subtitle {
   margin: -6px 0 14px;
   font-size: 13.5px;
   color: var(--iq-ink3);
   line-height: 1.5;
   max-width: 560px;
}
.iq-cc-chip { position: relative; }
.iq-cc-dot { width: 7px; height: 7px; border-radius: 999px; flex-shrink: 0; }
/* Category mark on the picker's chip rows — stroke takes the category colour
   via inline color; holds it on the dark active chip, same as the dot did. */
.iq-chip-glyph { width: 16px; height: 16px; flex-shrink: 0; display: block; }
/* Brand marks carry their own hex, and several are near-black (Angular,
   Ethereum) — on the active dark chip they must flip to paper or vanish.
   !important because the hex arrives as an inline style. */
.iq-pk-chip.is-on .iq-chip-glyph--brand { color: var(--iq-paper) !important; }
.iq-cc-chip.is-live:not(.is-on) {
   border-color: var(--iq-accentE);
   box-shadow: 0 0 0 2px var(--iq-accentS);
}
.iq-cc-videos {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 9.5px;
   font-weight: 400;
   color: var(--iq-accentD);
}
.iq-pk-chip.is-on .iq-cc-videos { color: #F8F7F4; }
.iq-cc-subhead {
   display: flex;
   align-items: center;
   gap: 10px;
   flex-wrap: wrap;
   margin-bottom: 11px;
}
.iq-cc-subhead-label { font-size: 14px; color: var(--iq-ink3); }
.iq-cc-subhead-label b { color: var(--iq-ink); font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em; font-weight: 600; }
.iq-cc-drill {
   margin-left: auto;
   display: inline-flex;
   align-items: center;
   gap: 6px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   font-weight: 400;
   color: var(--iq-accentD);
   text-decoration: none;
}

/* ---------- Stack heading ---------- */
.iq-stack-head {
   display: flex;
   align-items: baseline;
   gap: 12px;
   flex-wrap: wrap;
   margin-bottom: 13px;
}
.iq-stack-name {
   margin: 0;
   font-family: 'Instrument Sans', system-ui, sans-serif;
   font-size: 26px;
   font-weight: 600;
   letter-spacing: -0.035em;
   color: var(--iq-ink);
}
.iq-stack-blurb {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 13px;
   color: var(--iq-ink4);
}
@media (max-width: 879px) {
   .iq-stack-name { font-size: 22px; }
}

/* ============================================================================
   SUBJECT VIEW — sticky minimized nav + tabs
   ============================================================================ */
.iq-subject-nav {
   position: sticky;
   top: 64px;
   z-index: 20;
   background: var(--iq-paper);
   border-bottom: 1px solid var(--iq-rule);
   margin-bottom: 0;
   padding-top: 14px;
}
.iq-subject-nav-row {
   display: flex;
   align-items: center;
   gap: 15px;
}
.iq-subject-badge {
   width: 44px;
   height: 44px;
   flex-shrink: 0;
   color: #F8F7F4;
   display: grid;
   place-items: center;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 17px;
   font-weight: 400;
}
.iq-subject-badge.is-square { border-radius: 10px; }
.iq-subject-badge.is-circle { border-radius: 999px; }
.iq-subject-badge svg { width: 24px; height: 24px; display: block; }
.iq-subject-headings { flex: 1; min-width: 0; }
.iq-subject-eyebrow {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10.5px;
   font-weight: 400;
   letter-spacing: .1em;
   text-transform: uppercase;
   color: var(--iq-ink4);
   margin-bottom: 3px;
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
}
.iq-subject-title {
   font-family: 'Instrument Sans', system-ui, sans-serif;
   font-size: 30px;
   font-weight: 700;
   letter-spacing: -0.035em;
   color: var(--iq-ink);
   line-height: 1;
}
.iq-subject-period { color: var(--iq-subject, var(--iq-accent)); }
.iq-subject-stats {
   display: flex;
   gap: 20px;
   font-size: 14px;
   color: var(--iq-ink3);
   margin-right: 4px;
}
.iq-subject-stats b { font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em; font-weight: 600; font-size: 17px; color: var(--iq-ink); }
.iq-subject-stats .is-accent b { color: var(--iq-accent); }
.iq-change-subject {
   display: inline-flex;
   align-items: center;
   gap: 8px;
   padding: 9px 15px;
   border-radius: 999px;
   background: var(--iq-dark);
   color: var(--iq-paper);
   font-size: 14px;
   font-weight: 600;
   text-decoration: none;
   flex-shrink: 0;
}
.iq-change-subject-short { display: none; }
/* Back affordance shown above the inline "Change subject" picker. */
.iq-change-back {
   appearance: none;
   border: none;
   background: transparent;
   cursor: pointer;
   display: inline-flex;
   align-items: center;
   gap: 7px;
   padding: 6px 0;
   margin-bottom: 4px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 13px;
   font-weight: 400;
   color: var(--iq-ink3);
   transition: color 0.12s ease;
}
.iq-change-back:hover { color: var(--iq-ink); }
.iq-change-back svg { flex-shrink: 0; }
.iq-subject-tabs {
   display: flex;
   gap: 2px;
   margin-top: 14px;
   overflow-x: auto;
}
.iq-subject-tab {
   appearance: none;
   border: none;
   background: transparent;
   cursor: pointer;
   display: inline-flex;
   align-items: center;
   gap: 7px;
   padding: 11px 15px;
   font-size: 14.5px;
   font-weight: 500;
   color: var(--iq-ink3);
   border-bottom: 2px solid transparent;
   white-space: nowrap;
   margin-bottom: -1px;
}
.iq-subject-tab.is-on {
   font-weight: 600;
   color: var(--iq-ink);
   border-bottom-color: var(--iq-subject, var(--iq-accent));
}
.iq-tab-count {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   color: var(--iq-ink5);
}
.iq-subject-tab.is-on .iq-tab-count { color: var(--iq-ink4); }
.iq-tabpanels { padding-top: 28px; }
@media (max-width: 879px) {
   .iq-subject-nav { top: 56px; }
   .iq-subject-title { font-size: 23px; }
   .iq-subject-badge { width: 36px; height: 36px; font-size: 14px; }
   .iq-subject-stats { display: none; }
   .iq-change-subject-full { display: none; }
   .iq-change-subject-short { display: inline; }
   .iq-tabpanels { padding-top: 22px; }
}

/* ---------- Questions tab: filter bar ---------- */
.iq-qfilter {
   display: flex;
   align-items: center;
   gap: 8px;
   flex-wrap: wrap;
   margin-bottom: 14px;
}
.iq-qchip {
   appearance: none;
   cursor: pointer;
   display: inline-flex;
   align-items: center;
   gap: 7px;
   padding: 7px 13px;
   border-radius: 999px;
   font-size: 13.5px;
   font-weight: 600;
   color: var(--iq-ink4);
   background: transparent;
   border: 1px solid var(--iq-rule);
}
.iq-qchip.is-on { color: var(--iq-ink); background: var(--iq-card); border-color: var(--iq-rule2); }
.iq-qchip-dot { width: 7px; height: 7px; border-radius: 999px; background: var(--iq-ink5); }
.iq-qchip.is-on .iq-qchip-dot { background: var(--dot, var(--iq-ink5)); }
.iq-qchip-beginner { --dot: var(--iq-greenDot); }
.iq-qchip-intermediate { --dot: var(--iq-amberDot); }
.iq-qchip-advanced, .iq-qchip-expert { --dot: var(--iq-roseDot); }
.iq-qfilter-divider { width: 1px; height: 22px; background: var(--iq-rule); margin: 0 4px; }
.iq-qfilter-spacer { flex: 1; min-width: 8px; }
.iq-qsearch {
   display: inline-flex;
   align-items: center;
   gap: 8px;
   padding: 7px 12px;
   border-radius: 9px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   min-width: 200px;
   color: var(--iq-ink4);
}
.iq-qsearch input {
   appearance: none;
   border: none;
   background: transparent;
   outline: none;
   flex: 1;
   min-width: 0;
   font-size: 14px;
   color: var(--iq-ink);
   font-family: 'Instrument Sans', sans-serif;
}
@media (max-width: 879px) {
   .iq-qsearch { min-width: 100%; }
}

/* ---------- Questions tab: row extras ---------- */
.iq-row-lock { color: var(--iq-ink5); flex-shrink: 0; }
.iq-bm-btn {
   appearance: none;
   border: none;
   background: transparent;
   cursor: pointer;
   color: var(--iq-ink5);
   display: grid;
   place-items: center;
   padding: 2px;
   flex-shrink: 0;
}
.iq-bm-btn.is-on { color: var(--iq-accent); }
.iq-lock-card {
   display: flex;
   align-items: center;
   gap: 14px;
   padding: 18px 20px;
   border-radius: 12px;
   background: var(--iq-accentS);
   border: 1px solid var(--iq-accentE);
}
.iq-lock-icon {
   width: 38px;
   height: 38px;
   border-radius: 999px;
   background: #F8F7F4;
   color: var(--iq-accentD);
   display: grid;
   place-items: center;
   flex-shrink: 0;
}
.iq-lock-text { flex: 1; }
.iq-lock-title { margin: 0 0 2px; font-size: 15px; font-weight: 600; color: var(--iq-ink); }
.iq-lock-sub { margin: 0; font-size: 13.5px; color: var(--iq-ink3); }
.iq-lock-cta { flex-shrink: 0; }

/* ---------- Tab panels (deep dives / refreshers / cheatsheet) ---------- */
.iq-tabpanel { max-width: 880px; }
.iq-panel-head { margin-bottom: 18px; }
.iq-panel-eyebrow {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   font-weight: 400;
   letter-spacing: .06em;
   text-transform: uppercase;
   color: var(--iq-accentD);
   margin-bottom: 6px;
}
.iq-panel-title {
   margin: 0;
   font-family: 'Instrument Sans', system-ui, sans-serif;
   font-size: 24px;
   font-weight: 600;
   letter-spacing: -0.035em;
   color: var(--iq-ink);
}
.iq-panel-sub {
   margin: 8px 0 0;
   font-size: 15.5px;
   color: var(--iq-ink3);
   max-width: 560px;
}
.iq-card-grid-2 {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 12px;
}
@media (max-width: 879px) {
   .iq-card-grid-2 { grid-template-columns: 1fr; }
}

/* Deep-dive cards */
.iq-dive-card {
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 12px;
   padding: 18px;
   display: flex;
   flex-direction: column;
   gap: 9px;
   /* Became an <a> when the deep-dives tab stopped being a dead end; these
      keep it looking identical to the div it replaced. */
   color: inherit;
   text-decoration: none;
   transition: border-color .15s ease, background .15s ease;
}
a.iq-dive-card:hover {
   border-color: var(--iq-accent, var(--lts-orange, #E55A12));
   background: var(--iq-cardHover, var(--iq-card));
}
a.iq-dive-card:focus-visible {
   outline: 2px solid var(--lts-orange, #E55A12);
   outline-offset: 2px;
}
.iq-dive-top { display: flex; align-items: center; gap: 10px; }
.iq-dive-tag {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10.5px;
   font-weight: 400;
   letter-spacing: .06em;
   text-transform: uppercase;
   color: var(--iq-ink3);
   background: var(--iq-paper2);
   border-radius: 999px;
   padding: 3px 9px;
}
.iq-dive-eta {
   margin-left: auto;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   color: var(--iq-ink4);
}
.iq-dive-title { font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em; font-size: 19px; font-weight: 600; color: var(--iq-ink); line-height: 1.25; }
.iq-dive-blurb { margin: 0; font-size: 14px; color: var(--iq-ink3); line-height: 1.5; }

/* Refresher video cards */
.iq-video-card {
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 12px;
   overflow: hidden;
   text-decoration: none;
   display: block;
}
.iq-video-thumb {
   aspect-ratio: 16 / 9;
   background: linear-gradient(135deg, #232320, #232320);
   background-size: cover;
   background-position: center;
   display: grid;
   place-items: center;
   position: relative;
}
.iq-video-play {
   width: 44px;
   height: 44px;
   border-radius: 999px;
   background: var(--iq-accent);
   display: grid;
   place-items: center;
}
.iq-video-dur {
   position: absolute;
   bottom: 9px;
   right: 9px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   font-weight: 400;
   color: #F8F7F4;
   background: rgba(0, 0, 0, .6);
   border-radius: 5px;
   padding: 2px 6px;
}
.iq-video-pro {
   position: absolute;
   top: 9px;
   left: 9px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   font-weight: 400;
   text-transform: uppercase;
   color: #F8F7F4;
   background: var(--iq-accent);
   border-radius: 5px;
   padding: 2px 7px;
}
.iq-video-title { padding: 12px 14px; font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em; font-size: 16.5px; font-weight: 600; color: var(--iq-ink); }

/* Refresher bridge (technology → concept tracks) */
.iq-bridge-card {
   display: flex;
   align-items: flex-start;
   gap: 14px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 14px;
   padding: 24px 26px;
   margin-bottom: 22px;
}
.iq-bridge-icon {
   width: 40px;
   height: 40px;
   border-radius: 10px;
   background: var(--iq-accentS);
   color: var(--iq-accentD);
   display: grid;
   place-items: center;
   flex-shrink: 0;
}
.iq-bridge-title { margin: 0 0 8px; font-family: 'Instrument Sans', system-ui, sans-serif; font-size: 22px; font-weight: 600; letter-spacing: -0.035em; color: var(--iq-ink); }
.iq-bridge-sub { margin: 0; font-size: 15px; color: var(--iq-ink3); line-height: 1.6; }
.iq-bridge-track {
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 12px;
   padding: 16px;
   display: flex;
   flex-direction: column;
   gap: 10px;
   text-decoration: none;
}
.iq-bridge-track.is-live { border-color: var(--iq-accentE); box-shadow: 0 0 0 3px var(--iq-accentS); }
.iq-bridge-track-top { display: flex; align-items: center; gap: 11px; }
.iq-bridge-track-dot { width: 12px; height: 12px; border-radius: 999px; flex-shrink: 0; }
.iq-bridge-track-name { flex: 1; font-size: 16px; font-weight: 600; font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em; color: var(--iq-ink); }
.iq-bridge-track-tag {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   font-weight: 400;
   letter-spacing: .06em;
   text-transform: uppercase;
   color: var(--iq-ink4);
   border: 1px dashed var(--iq-rule2);
   border-radius: 999px;
   padding: 3px 8px;
}
.iq-bridge-track-tag.is-live { color: var(--iq-accentD); background: var(--iq-accentS); border: 1px solid var(--iq-accentE); }
.iq-bridge-track-blurb { margin: 0; font-size: 13.5px; color: var(--iq-ink3); line-height: 1.5; }

/* Coming-soon card */
.iq-coming-card {
   max-width: 720px;
   background: var(--iq-card);
   border: 1px dashed var(--iq-accentE);
   border-radius: 14px;
   padding: 28px 30px;
   text-align: center;
}
.iq-coming-icon {
   width: 46px;
   height: 46px;
   border-radius: 999px;
   background: var(--iq-accentS);
   color: var(--iq-accentD);
   display: grid;
   place-items: center;
   margin: 0 auto 14px;
}
.iq-coming-title { margin: 0 0 8px; font-family: 'Instrument Sans', system-ui, sans-serif; font-size: 23px; font-weight: 600; letter-spacing: -0.035em; color: var(--iq-ink); }
.iq-coming-sub { margin: 0 auto 16px; font-size: 15px; color: var(--iq-ink3); line-height: 1.6; max-width: 440px; }

/* Cheatsheet tab — link card teasing the sheet; the content lives on its own
   page. Styled as a miniature contents page: dark meta band up top (matches
   the page's dark buttons/chips), document title, book-style dotted-leader
   TOC where each section title runs to its position number. */
.iq-sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.iq-sheet-card {
   display: block;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 14px;
   overflow: hidden;
   text-decoration: none;
   color: inherit;
   transition: border-color .15s ease, box-shadow .15s ease;
}
.iq-sheet-card:hover { border-color: var(--iq-ink5); box-shadow: 0 6px 18px rgba(35,35,32, .07); }
.iq-sheet-card:hover .iq-sheet-open { color: var(--iq-accentD); }
.iq-sheet-band {
   display: flex;
   align-items: center;
   gap: 10px;
   background: var(--iq-dark);
   padding: 9px 20px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   font-weight: 400;
   letter-spacing: .08em;
   text-transform: uppercase;
}
.iq-sheet-band-label { color: var(--iq-paper); }
.iq-sheet-band-meta { margin-left: auto; color: rgba(233,232,227, .62); }
.iq-sheet-pro {
   font-size: 10px;
   font-weight: 700;
   letter-spacing: .06em;
   color: #F8F7F4;
   background: var(--iq-accent);
   border-radius: 5px;
   padding: 2px 7px;
   flex-shrink: 0;
}
.iq-sheet-body { padding: 20px 20px 18px; }
.iq-sheet-title { margin: 0; font-family: 'Instrument Sans', system-ui, sans-serif; font-size: 22px; font-weight: 600; letter-spacing: -0.035em; color: var(--iq-ink); }
/* Study-guide tab card uses a subtitle instead of a dotted-leader TOC. */
.iq-sheet-sub { margin: 8px 0 0; font-family: 'Instrument Sans', system-ui, sans-serif; font-size: 14px; line-height: 1.55; color: var(--iq-ink2, #45443E); }
.iq-sheet-sub em { font-style: italic; color: var(--iq-accent, #E55A12); }
/* Two columns filled top-to-bottom (like a real contents page) — CSS multicol
   rather than grid so 01–07 read down the left column, 08+ down the right. */
.iq-sheet-toc {
   list-style: none;
   margin: 16px 0 -9px;
   padding: 16px 0 0;
   border-top: 1px solid var(--iq-divider);
   columns: 2;
   column-gap: 32px;
}
.iq-sheet-toc li { display: flex; align-items: baseline; font-size: 14.5px; color: var(--iq-ink2); min-width: 0; break-inside: avoid; margin-bottom: 9px; }
.iq-sheet-toc-t { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
/* Dotted leader between title and number — ordered after the title via flex
   `order` on the number span (pseudo-elements sit in source order otherwise). */
.iq-sheet-toc li::after {
   content: "";
   flex: 1;
   min-width: 20px;
   margin: 0 7px;
   border-bottom: 1px dotted var(--iq-ink5);
   align-self: flex-end;
   margin-bottom: 4px;
}
.iq-sheet-toc-n { order: 1; font-family: 'Fragment Mono', ui-monospace, monospace; font-size: 11px; font-weight: 400; color: var(--iq-ink4); flex-shrink: 0; }
.iq-sheet-toc li.iq-sheet-toc-more { font-size: 13.5px; color: var(--iq-ink4); font-style: italic; }
.iq-sheet-toc li.iq-sheet-toc-more::after { content: none; }
.iq-sheet-foot {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 10px;
   border-top: 1px solid var(--iq-divider);
   padding: 13px 20px;
}
.iq-sheet-open { font-size: 14px; font-weight: 600; color: var(--iq-ink2); }
.iq-sheet-foot-arrow { color: var(--iq-ink3); transition: transform .15s ease, color .15s ease; }
.iq-sheet-card:hover .iq-sheet-foot-arrow { transform: translateX(3px); color: var(--iq-accentD); }
@media (prefers-reduced-motion: reduce) {
   .iq-sheet-foot-arrow { transition: none; }
   .iq-sheet-card:hover .iq-sheet-foot-arrow { transform: none; }
}
@media (max-width: 879px) {
   .iq-sheet-band { padding: 8px 16px; flex-wrap: wrap; gap: 8px; }
   .iq-sheet-band-meta { margin-left: 0; }
   .iq-sheet-body { padding: 16px 16px 14px; }
   .iq-sheet-foot { padding: 12px 16px; }
   .iq-sheet-toc { columns: 1; }
}

/* ---------- AI "Visualize" archetypes (.iqv-*) ----------
   Figure-plate design system. Markup emitted server-side by
   services/visualizationRenderer.js and injected into .iq-ai-result via the
   explainPanel x-html swap. This base block owns STRUCTURE (grids, layout,
   steppers, reveal, fullscreen); the visual identity is the TRANSIT SKIN
   layer further down, which overrides the surface styles here (signage-bar
   head, station cards, thick route lines, roundel dots). Interactions are
   delegated handlers in iqv-interactions.js; route connectors for
   states/system are drawn by iqv-connectors.js. */
.iqv {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 14px;
   color: var(--iq-ink2);
}
.iqv-plate {
   position: relative; /* anchors the ::after watermark */
   background: #F8F7F4;
   border: 1px solid var(--iq-rule);
   border-radius: 9px;
   padding: 18px 22px 20px;
   box-shadow: inset 0 2px 4px rgba(35,35,32,.09); /* inset well */
   /* Base readability bump: scales every archetype's hardcoded px type
      uniformly (hierarchy intact). iqv-interactions.js measures scale live so
      steppers/overlays are unaffected; .is-fullscreen overrides with its own
      zoom values below. */
   zoom: 1.08;
}
/* Copyright line - bottom-right corner, inside the plate's bottom padding so
   it never collides with captions or reveal chrome.

   TWO carriers, one look. `.iqv-plate-mark` is real markup emitted by
   visualizationRenderer.js: a pseudo-element vanishes when someone copies the
   plate's innerHTML, and lifting that markup is the actual theft path, so the
   attribution has to live in the DOM. The `::before` is the legacy carrier for
   figures cached before that change - suppressed below whenever the markup mark
   is present, so a rerendered figure never shows two. (Without :has() both
   render, overlapping identically: heavier, not broken.) Once
   scripts/rerender-visuals.js has swept all four cached-HTML surfaces, the
   ::before rule can go.

   The year stays a CSS concat with var(--lts-year) on BOTH carriers:
   iqv-interactions.js sets it to the live year on every figure page and the
   OG/social templates inline it, so cached figures need no rerender and no
   annual markup edit. The var's value MUST be a QUOTED string ('2026', quotes
   included) or the whole content computes to none. */
.iqv-plate::before,
.iqv-plate-mark {
   position: absolute;
   right: 14px;
   bottom: 7px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 9.5px;
   letter-spacing: .04em;
   color: var(--iq-ink4);
   pointer-events: none;
   user-select: none;
}
.iqv-plate::before      { content: '©LearnThatStack ' var(--lts-year, '2026'); }
.iqv-plate-mark::after  { content: ' ' var(--lts-year, '2026'); }
.iqv-plate:has(> .iqv-plate-mark)::before { content: none; }

/* Brand imprint — a faint diagonal "learnthatstack.com" tiled across the whole
   plate, so a cropped screenshot still carries the mark. Pure CSS (no figure
   rerender needed): one SVG tile as two offset background layers fakes a brick
   stagger with every mark fully inside its tile (no seam clipping). The tile's
   fill is solid ink4 (#94938B) so subtlety is tuned HERE via opacity alone;
   multiply keeps it reading as ink pressed into the paper rather than a gray
   film. SVG-as-background can't reach webfonts - generic monospace is
   deliberate. Re-enabled 2026-08-01 (user ask: screenshots must carry the
   mark). First revival shipped at .05 / 520x400 and the user could not SEE it
   on a real plate - a mid-gray multiplied onto near-white at .05 is ~2%
   darkening, and a 400px-tall tile puts only one sparse row on a wide short
   plate. Current tuning: 320px row pitch so every plate shape catches 2+ rows
   and any ~400px crop contains a mark; opacity .10 (~4% darkening) is the
   user-picked setting (2026-08-01, stepped down from .15) - it sits between
   the invisible .05 and the shouty .15, so keep changes within that band. */
.iqv-plate::after {
   content: '';
   position: absolute;
   inset: 0;
   border-radius: inherit;
   background-image:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='440' height='320'%3E%3Ctext transform='translate(50 190) rotate(-24)' font-family='monospace' font-size='16' fill='%2394938B'%3Elearnthatstack.com%3C/text%3E%3C/svg%3E"),
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='440' height='320'%3E%3Ctext transform='translate(50 190) rotate(-24)' font-family='monospace' font-size='16' fill='%2394938B'%3Elearnthatstack.com%3C/text%3E%3C/svg%3E");
   background-size: 440px 320px;
   background-position: 0 0, 220px 160px;
   opacity: .10;
   mix-blend-mode: multiply;
   pointer-events: none;
}
.iqv-plate-head {
   display: flex;
   align-items: baseline;
   justify-content: space-between;
   gap: 12px;
   flex-wrap: wrap;
   padding-bottom: 10px;
   border-bottom: 1px solid var(--iq-divider);
   margin-bottom: 18px;
}
/* The "Figure · <archetype>" eyebrow was dropped from the plate head; the
   renderer no longer emits it, but figures cached in question_explanations
   still carry the markup — keep it hidden here rather than re-generating. */
.iqv-plate-tag { display: none; }
.iqv-plate-title {
   font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em; font-weight: 600;
   font-style: normal;
   font-size: 15px;
   color: var(--iq-ink3);
}
.iqv-caption {
   font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em; font-weight: 600;
   font-style: normal;
   font-size: 14.5px; /* sits outside the zoomed plate — bumped with the site sweep */
   line-height: 1.6;
   color: var(--iq-ink3);
   margin: 18px 0 0;
}
.iqv .iqv-arrow { color: var(--iq-ink4); }

/* Tone dots — color demoted from chips to 7px marks; neutral gets none. */
.iqv-dot {
   display: inline-block;
   width: 7px;
   height: 7px;
   border-radius: 50%;
   margin-right: 7px;
   vertical-align: 1px;
}
.iqv-dot-g { background: var(--iq-greenDot); }
.iqv-dot-a { background: var(--iq-amberDot); }
.iqv-dot-r { background: var(--iq-roseDot); }
.iqv-dot-acc { background: var(--iq-accent); }

/* Tone renders ONLY as the dot above. The colored left rail that outcome
   cards, pipeline stages, timeline spans and trace tokens used to carry is
   gone: a stripe on some cards but not their neighbours made every figure
   read as a generic slide deck, and it fought the transit skin's rule that
   structure is drawn in ink and only semantics get color. The renderer still
   emits .iqv-tone-* (services/visualizationRenderer.js toneClass) — it is an
   inert annotation of the author's tone choice now, deliberately not styled.
   A lane's tone shows on its .iqv-lane-head dot, stated once. */

/* -- comparison: print table -------------------------------------------- */
.iqv-scroll { overflow-x: auto; }
.iqv-cmp {
   border-collapse: collapse;
   width: 100%;
   min-width: 480px;
}
.iqv-cmp th, .iqv-cmp td {
   text-align: left;
   vertical-align: top;
   padding: 11px 14px;
   border: 0;
}
.iqv-cmp thead th {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 15px;
   font-weight: 400;
   color: var(--iq-ink);
   padding-bottom: 9px;
   border-bottom: 1.5px solid var(--iq-cardEdge);
}
.iqv-cmp tbody th {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10.5px;
   font-weight: 400;
   letter-spacing: 0.1em;
   text-transform: uppercase;
   color: var(--iq-ink4);
   white-space: nowrap;
   padding-top: 14px;
   border-bottom: 1px solid var(--iq-divider);
}
.iqv-cmp tbody td {
   font-size: 13.5px;
   color: var(--iq-ink2);
   border-bottom: 1px solid var(--iq-divider);
}
.iqv-cmp tbody tr:last-child td,
.iqv-cmp tbody tr:last-child th { border-bottom: 0; }
.iqv-cmp td small {
   display: block;
   margin-top: 2px;
   font-size: 11.5px;
   color: var(--iq-ink4);
}
.iqv-cmp td.iqv-gotcha {
   background: rgba(194, 70, 50, 0.06);
   border-radius: 6px;
}
.iqv-cmp tfoot td {
   padding-top: 12px;
   border-top: 2px solid var(--iq-ink);
   font-size: 13.5px;
   color: var(--iq-ink);
}
.iqv-cmp tfoot b {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   font-weight: 400;
   letter-spacing: 0.14em;
   text-transform: uppercase;
   color: var(--iq-accentD);
   margin-bottom: 2px;
}

/* -- trace: the machine --------------------------------------------------- */
.iqv-trace-grid {
   display: grid;
   grid-template-columns: minmax(0, 10fr) minmax(0, 9fr);
   gap: 18px;
}
.iqv-code {
   background: #2A2A26;
   border-radius: 10px;
   padding: 12px 0;
   overflow-x: auto;
   align-self: start;
}
.iqv-cl {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12.5px;
   line-height: 1.95;
   color: #C6C5BE;
   white-space: pre;
   padding: 0 14px 0 10px;
   border-left: 3px solid transparent;
   display: flex;
   gap: 12px;
   transition: background .25s ease, border-color .25s ease;
}
.iqv-ln {
   color: #67665F;
   min-width: 14px;
   text-align: right;
   flex-shrink: 0;
   user-select: none;
   font-variant-numeric: tabular-nums;
}
.iqv-cl.is-hot {
   background: rgba(229, 90, 18, 0.15);
   border-left-color: var(--iq-accent);
   color: #E9E8E3;
}
.iqv-cl.is-hot .iqv-ln { color: var(--iq-accentE); }
/* Prism tags each line's <code>; strip the theme's inline-code chrome so
   tokens color the text without shifting the layout. */
.iqv-cl code[class*="language-"] {
   background: transparent;
   padding: 0;
   margin: 0;
   border: 0;
   border-radius: 0;
   font-family: inherit;
   font-size: inherit;
   line-height: inherit;
   color: inherit;
   white-space: pre;
   text-shadow: none;
}

.iqv-machine {
   display: flex;
   flex-direction: column;
   gap: 14px;
   min-width: 0;
}
.iqv-lane-head {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   font-weight: 400;
   letter-spacing: 0.14em;
   text-transform: uppercase;
   color: var(--iq-ink3);
   display: flex;
   justify-content: space-between;
   align-items: baseline;
   gap: 8px;
   margin-bottom: 6px;
}
/* A lane's tone reads here, once, instead of on every token — sized down to
   sit inside the 10px uppercase label. */
.iqv-lane-head .iqv-dot { width: 6px; height: 6px; margin-right: 6px; vertical-align: 0; }
.iqv-lane-hint {
   font-weight: 400;
   letter-spacing: 0.02em;
   text-transform: none;
   font-size: 10.5px;
   color: var(--iq-ink4);
}
/* A stack looks like a stack: vertical well, floor line, tokens pile upward. */
.iqv-stackwell {
   display: flex;
   flex-direction: column-reverse;
   align-items: flex-start;
   gap: 5px;
   min-height: 78px;
   border-bottom: 2px solid var(--iq-cardEdge);
   padding-bottom: 6px;
}
/* Queues run horizontal (FIFO). */
.iqv-queuerow {
   display: flex;
   gap: 6px;
   align-items: center;
   min-height: 32px;
   border-bottom: 1px solid var(--iq-divider);
   padding-bottom: 6px;
   flex-wrap: wrap;
}
.iqv-tok {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 6px;
   padding: 3px 9px;
   box-shadow: 0 1px 1px rgba(35,35,32, 0.05);
   color: var(--iq-ink2);
}
.iqv-tok.is-new { animation: iqvTokIn .22s ease both; }
@keyframes iqvTokIn { from { opacity: 0; transform: translateY(6px); } }
.iqv-empty {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   letter-spacing: 0.06em;
   color: var(--iq-ink4);
   padding: 4px 0;
}

.iqv-console {
   background: #2A2A26;
   border-radius: 8px;
   padding: 9px 13px 11px;
   min-height: 56px;
}
.iqv-console .iqv-lane-head { color: #8A897F; margin-bottom: 4px; }
.iqv-cline {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   line-height: 1.75;
   color: #93D0AF;
   display: flex;
   gap: 8px;
}
.iqv-cline::before { content: "›"; color: #67665F; }
.iqv-cline.is-new { animation: iqvCIn .5s ease both; }
@keyframes iqvCIn { from { background: rgba(46, 165, 107, 0.25); } }

/* Narration is the reading voice — unboxed, 15px, behind a big step numeral. */
.iqv-narr {
   display: flex;
   gap: 14px;
   align-items: flex-start;
   margin-top: 18px;
}
.iqv-stepnum {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 21px;
   font-weight: 400;
   color: var(--iq-accentD);
   line-height: 1.1;
   min-width: 30px;
   text-align: center;
   font-variant-numeric: tabular-nums;
}
.iqv-stepnum small {
   display: block;
   font-size: 9px;
   font-weight: 600;
   letter-spacing: 0.12em;
   text-transform: uppercase;
   color: var(--iq-ink4);
}
.iqv-narr p {
   margin: 0;
   font-size: 15px;
   line-height: 1.55;
   color: var(--iq-ink);
}

.iqv-stepbar {
   display: flex;
   align-items: center;
   gap: 14px;
   margin-top: 14px;
   flex-wrap: wrap;
}
.iqv-stepbtn {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13px;
   font-weight: 600;
   background: var(--iq-card);
   color: var(--iq-ink);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 7px;
   padding: 6px 14px;
   cursor: pointer;
   transition: border-color .15s ease, opacity .15s ease;
}
.iqv-stepbtn:hover:not(:disabled) { border-color: var(--iq-ink); }
.iqv-stepbtn:disabled { opacity: .35; cursor: default; }
.iqv-stepbtn:focus-visible, .iqv-probe:focus-visible { outline: 2px solid var(--iq-accent); outline-offset: 1px; }
.iqv-track {
   flex: 1;
   min-width: 80px;
   height: 2px;
   background: var(--iq-divider);
   border-radius: 2px;
   overflow: hidden;
}
.iqv-track i {
   display: block;
   height: 100%;
   background: var(--iq-accent);
   width: 0;
   transition: width .3s ease;
}
.iqv-stepcount {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   color: var(--iq-ink3);
   font-variant-numeric: tabular-nums;
}
.iqv-keyhint {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10.5px;
   color: var(--iq-ink4);
}
@media (pointer: coarse) { .iqv-keyhint { display: none; } }

/* -- states: drawn connectors ---------------------------------------------
   (wrapper is .iqv-stateswrap — the plate itself carries .iqv-states) */
.iqv-stateswrap {
   display: flex;
   align-items: center;
   justify-content: flex-start;
   gap: 0;
   overflow-x: auto;
   padding: 6px 0 2px;
}
.iqv-scol {
   display: flex;
   flex-direction: column;
   gap: 14px;
   flex-shrink: 0;
}
.iqv-sgap {
   display: flex;
   flex-direction: column;
   justify-content: center;
   gap: 24px;
   padding: 0 8px;
   flex-shrink: 0;
}
/* Overflow affordance (iqv-interactions.js toggles .is-overflowing): a thin
   always-there bar plus a right-edge fade while content remains rightward —
   macOS overlay scrollbars alone leave clipped boards looking complete. */
.iqv-stateswrap, .iqv-scroll { scrollbar-width: thin; scrollbar-color: var(--iq-rule) transparent; }
.iqv-stateswrap::-webkit-scrollbar, .iqv-scroll::-webkit-scrollbar { height: 6px; }
.iqv-stateswrap::-webkit-scrollbar-track, .iqv-scroll::-webkit-scrollbar-track { background: transparent; }
.iqv-stateswrap::-webkit-scrollbar-thumb, .iqv-scroll::-webkit-scrollbar-thumb { background: var(--iq-rule); border-radius: 3px; }
.iqv-stateswrap.is-overflowing, .iqv-scroll.is-overflowing {
   -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 44px), rgba(0, 0, 0, 0.08));
   mask-image: linear-gradient(to right, #000 calc(100% - 44px), rgba(0, 0, 0, 0.08));
}
@media print {
   .iqv-stateswrap, .iqv-scroll { mask-image: none; -webkit-mask-image: none; }
}
.iqv-snode {
   position: relative;
   z-index: 1;
   background: var(--iq-card);
   border: 1.5px solid var(--iq-cardEdge);
   border-radius: 8px;
   padding: 10px 16px;
   text-align: center;
   min-width: 108px;
   transition: transform .15s ease, box-shadow .15s ease;
}
.iqv-snode:hover {
   transform: translateY(-1px);
   box-shadow: 0 2px 6px rgba(35,35,32, 0.08);
}
.iqv-snode-label {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 13.5px;
   font-weight: 400;
   color: var(--iq-ink);
}
.iqv-snode-note {
   display: block;
   font-size: 11px;
   color: var(--iq-ink3);
   margin-top: 2px;
}
.iqv-conn {
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 3px;
}
.iqv-conn-label {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10.5px;
   color: var(--iq-ink3);
   white-space: nowrap;
   transition: color .15s ease;
}
.iqv-conn-line {
   position: relative;
   width: 78px;
   height: 1.5px;
   background: #B5B4AC;
   transition: background .15s ease;
}
.iqv-conn-line::after {
   content: "";
   position: absolute;
   right: -1px;
   top: -3.4px;
   border-left: 7px solid #B5B4AC;
   border-top: 4px solid transparent;
   border-bottom: 4px solid transparent;
   transition: border-left-color .15s ease;
}
.iqv-conn.is-hot .iqv-conn-line { background: var(--iq-accent); }
.iqv-conn.is-hot .iqv-conn-line::after { border-left-color: var(--iq-accent); }
.iqv-conn.is-hot .iqv-conn-label { color: var(--iq-accentD); }
.iqv-strans {
   list-style: none;
   margin: 12px 0 0;
   padding: 0;
   display: flex;
   flex-direction: column;
   gap: 4px;
   font-size: 12.5px;
   color: var(--iq-ink3);
}
.iqv-strans li { margin: 0; }
.iqv-strans code {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 4px;
   padding: 1px 5px;
   color: var(--iq-ink);
}
.iqv-strans-via { color: var(--iq-ink4); }

/* -- chain: the metro spine ------------------------------------------------ */
.iqv-probes {
   display: flex;
   align-items: center;
   gap: 8px;
   flex-wrap: wrap;
   margin: 0 0 18px;
}
.iqv-probes-label {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   font-weight: 400;
   letter-spacing: 0.14em;
   text-transform: uppercase;
   color: var(--iq-ink3);
}
.iqv-probe {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   color: var(--iq-ink);
   border-radius: 6px;
   padding: 4px 11px;
   cursor: pointer;
   transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.iqv-probe:hover { border-color: var(--iq-ink); }
.iqv-probe.is-on {
   background: var(--iq-ink);
   border-color: var(--iq-ink);
   color: var(--iq-paper);
}
.iqv-chainwrap {
   position: relative;
   display: flex;
   flex-direction: column;
   align-items: center;
}
.iqv-spine {
   position: absolute;
   top: 10px;
   bottom: 10px;
   left: 50%;
   width: 2px;
   margin-left: -1px;
   background: var(--iq-cardEdge);
   z-index: 0;
}
.iqv-spine-fill {
   position: absolute;
   top: 10px;
   left: 50%;
   width: 2px;
   margin-left: -1px;
   background: var(--iq-accent);
   height: 0;
   z-index: 0;
   transition: height .45s ease;
}
.iqv-cbox {
   position: relative;
   z-index: 1;
   background: var(--iq-card);
   border: 1.5px solid var(--iq-cardEdge);
   border-radius: 8px;
   padding: 9px 16px;
   transition: border-color .2s ease, background .2s ease;
}
.iqv-cbox.is-lit { border-color: var(--iq-amberDot); background: var(--iq-amberS); }
.iqv-cbox.is-hit { border-color: var(--iq-greenDot); background: var(--iq-greenS); }
.iqv-cbox-title {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 13px;
   font-weight: 400;
   color: var(--iq-ink);
}
.iqv-cbox-note {
   display: block;
   font-size: 11px;
   color: var(--iq-ink3);
   margin-top: 1px;
}
.iqv-cbox ul {
   list-style: none;
   margin: 5px 0 0;
   padding: 0;
}
.iqv-cbox li {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   color: var(--iq-ink3);
   line-height: 1.75;
   margin: 0;
}
.iqv-cbox li.is-match {
   color: var(--iq-green);
   font-weight: 600;
   animation: iqvFlare 1s ease;
}
@keyframes iqvFlare {
   0% { background: var(--iq-greenS); }
   40% { background: rgba(46,158,107,.35); }
   100% { background: transparent; }
}
.iqv-clink {
   position: relative;
   z-index: 1;
   padding: 7px 0;
   min-height: 10px;
}
.iqv-clink span {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   color: var(--iq-ink4);
   background: #F8F7F4;
   border: 1px solid var(--iq-divider);
   border-radius: 99px;
   padding: 1px 7px;
}
.iqv-probe-result {
   margin: 16px 0 0;
   font-size: 13.5px;
   color: var(--iq-ink2);
   min-height: 1.5em;
}
.iqv-probe-result.is-miss { color: var(--iq-rose); }
.iqv-probe-result .iqv-dot { margin-right: 8px; }

/* -- sequence: actors and lifelines ----------------------------------------
   Lifeline offsets and each message's grid-column/row are computed server-
   side; the stepper reuses trace's narration + stepbar chrome verbatim. */
.iqv-seqwrap { position: relative; }
.iqv-lifeline {
   position: absolute;
   top: 16px;
   bottom: 4px;
   width: 0;
   border-left: 1px dashed var(--iq-rule2);
   z-index: 0;
}
.iqv-seq {
   position: relative;
   display: grid;
   row-gap: 2px;
   z-index: 1;
}
.iqv-actor {
   justify-self: center;
   min-width: 0;
   max-width: 100%;
   background: var(--iq-card);
   border: 1.5px solid var(--iq-cardEdge);
   border-radius: 8px;
   padding: 7px 14px;
   margin-bottom: 8px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12.5px;
   font-weight: 400;
   color: var(--iq-ink);
   text-align: center;
   overflow-wrap: break-word;
}
.iqv-msg {
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 2px;
   min-width: 0;
   /* Pads by half of one spanned column each side, so the line runs exactly
      lifeline-center to lifeline-center. --iqv-span is set inline. */
   padding: 6px calc(50% / var(--iqv-span, 1));
   transition: opacity .2s ease;
}
.iqv-msg.is-self { padding: 6px 0; }
.iqv-msg-label {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11px;
   color: var(--iq-ink2);
   background: #F8F7F4; /* masks the lifeline running behind the text */
   border-radius: 4px;
   padding: 0 6px;
   text-align: center;
   max-width: 100%;
   transition: color .15s ease;
}
.iqv-msg.is-self .iqv-msg-label {
   border: 1px solid var(--iq-divider);
   border-radius: 99px;
   padding: 1px 9px;
}
.iqv-msg-line {
   align-self: stretch;
   position: relative;
   height: 0;
   border-top: 1.5px solid #B5B4AC;
   transition: border-color .15s ease;
}
.iqv-msg-line::after {
   content: "";
   position: absolute;
   top: -3.25px;
   border-top: 4px solid transparent;
   border-bottom: 4px solid transparent;
}
.iqv-msg.is-ltr .iqv-msg-line::after { right: -1px; border-left: 7px solid #B5B4AC; }
.iqv-msg.is-rtl .iqv-msg-line::after { left: -1px; border-right: 7px solid #B5B4AC; }
.iqv-msg.is-async .iqv-msg-line,
.iqv-msg.is-return .iqv-msg-line { border-top-style: dashed; }
.iqv-msg.is-return .iqv-msg-line { border-top-color: var(--iq-ink5); }
.iqv-msg.is-return.is-ltr .iqv-msg-line::after { border-left-color: var(--iq-ink5); }
.iqv-msg.is-return.is-rtl .iqv-msg-line::after { border-right-color: var(--iq-ink5); }
.iqv-msg.is-future { opacity: .3; }
.iqv-msg.is-now .iqv-msg-label { color: var(--iq-accentD); font-weight: 600; }
.iqv-msg.is-now .iqv-msg-line { border-top-color: var(--iq-accent); }
.iqv-msg.is-now.is-ltr .iqv-msg-line::after { border-left-color: var(--iq-accent); }
.iqv-msg.is-now.is-rtl .iqv-msg-line::after { border-right-color: var(--iq-accent); }

/* -- memory: names and the heap --------------------------------------------
   Badge numbers stand in for drawn pointers; the client additionally draws
   connector rails (SVG overlay per panel) from each reference badge to its
   object card. Hover/tap a badge to light its pair (panel-scoped JS). */
.iqv-mem { display: grid; gap: 16px; padding: 2px 0; }
.iqv-mem[data-iqv-panels="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.iqv-mem[data-iqv-panels="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.iqv-mpanel {
   position: relative; /* anchors the .iqv-mlinks connector overlay */
   border: 1px solid var(--iq-divider);
   border-radius: 10px;
   padding: 12px 14px;
   min-width: 0;
}
.iqv-mpanel-label {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   font-weight: 400;
   letter-spacing: 0.14em;
   text-transform: uppercase;
   color: var(--iq-accentD);
   margin-bottom: 10px;
}
.iqv-mcode {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   color: var(--iq-ink);
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 6px;
   padding: 5px 9px;
   margin: 0 0 10px;
   overflow-x: auto;
   white-space: nowrap;
}
.iqv-mnote {
   font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em; font-weight: 600;
   font-style: normal;
   font-size: 12.5px;
   line-height: 1.55;
   color: var(--iq-ink3);
   margin: 10px 0 0;
}
.iqv-mvars { margin-bottom: 14px; }
.iqv-mvar {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 10px;
   padding: 6px 2px;
   border-bottom: 1px solid var(--iq-divider);
}
.iqv-mvar:last-child { border-bottom: 0; }
.iqv-mvar-name {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12.5px;
   font-weight: 400;
   color: var(--iq-ink);
}
.iqv-mcell { display: inline-flex; align-items: center; min-width: 0; }
.iqv-mval {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   color: var(--iq-ink2);
}
.iqv-mval-empty { color: var(--iq-ink5); }
.iqv-mrefbadge {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   width: 18px;
   height: 18px;
   border-radius: 50%;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10.5px;
   font-weight: 400;
   color: var(--iq-ink2);
   background: var(--iq-card);
   border: 1.5px solid var(--iq-cardEdge);
   flex-shrink: 0;
   transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.iqv-mrefbadge.is-hot {
   border-color: var(--iq-accent);
   color: var(--iq-accentD);
   background: var(--iq-accentS);
}
.iqv-mheap { display: flex; flex-direction: column; gap: 10px; }
.iqv-mobj {
   background: var(--iq-card);
   border: 1.5px solid var(--iq-cardEdge);
   border-radius: 8px;
   padding: 9px 12px;
   transition: border-color .15s ease, box-shadow .15s ease;
}
.iqv-mobj.is-target {
   border-color: var(--iq-accent);
   box-shadow: 0 2px 6px rgba(35,35,32, 0.08);
}
.iqv-mobj-head { display: flex; align-items: center; gap: 8px; margin-bottom: 3px; }
.iqv-mobj-title {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12.5px;
   font-weight: 400;
   color: var(--iq-ink);
}
.iqv-mfield {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 10px;
   padding: 3px 0 3px 26px;
}
.iqv-mfield-name {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   color: var(--iq-ink2);
}

/* Consecutive-panel diff (server-derived classes): what appeared or changed
   pops, carry-overs recede, ghost slots hold rows so panels stay aligned. */
.iqv-mvar.is-new, .iqv-mvar.is-changed {
   background: var(--iq-accentS);
   border-radius: 6px;
   margin: 0 -6px;
   padding-left: 8px;
   padding-right: 8px;
}
.iqv-mfield.is-new, .iqv-mfield.is-changed {
   background: var(--iq-accentS);
   border-radius: 6px;
   margin: 0 -6px;
   padding-left: 32px; /* the 26px ref indent + the 6px bleed */
   padding-right: 8px;
}
.iqv-mvar.is-same, .iqv-mfield.is-same, .iqv-mobj.is-same { opacity: 0.62; }
.iqv-mvar.is-ghost { visibility: hidden; }
.iqv-mobj.is-new { border-color: var(--iq-accent); }
.iqv-mmark {
   display: inline-block;
   margin-left: 7px;
   padding: 1px 5px;
   border-radius: 4px;
   background: var(--iq-accent);
   color: #F8F7F4;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 9px;
   font-weight: 400;
   letter-spacing: 0.08em;
   text-transform: uppercase;
   vertical-align: 1px;
}

/* Connector rails (client-drawn SVG overlay, iqv-interactions.js): reference
   badge → its object card, routed down the panel's right padding. Rails for
   the same object id share an x, so two names on one object visibly merge. */
.iqv-mlinks {
   position: absolute;
   inset: 0;
   width: 100%;
   height: 100%;
   pointer-events: none;
   overflow: visible;
}
.iqv-mlink path {
   fill: none;
   stroke: #B5B4AC;
   stroke-width: 1.5;
   transition: stroke 0.15s ease;
}
.iqv-mlink circle { fill: #B5B4AC; transition: fill 0.15s ease; }
.iqv-mlink.is-hot path { stroke: var(--iq-accent); }
.iqv-mlink.is-hot circle { fill: var(--iq-accent); }
/* only referencing badges are clickable — the head badge on a card is inert */
.iqv-mrefbadge[data-iqv-ref] { cursor: pointer; }

/* One-time discoverability pulse when the plate first draws its rails; the
   global reduced-motion rule kills it. */
.iqv-mrefbadge.is-pulse { animation: iqv-mpulse 1.1s ease-out 1 0.15s backwards; }
@keyframes iqv-mpulse {
   0% { box-shadow: 0 0 0 0 rgba(229, 90, 18, 0.4); }
   70% { box-shadow: 0 0 0 7px rgba(229, 90, 18, 0); }
   100% { box-shadow: 0 0 0 0 rgba(229, 90, 18, 0); }
}

/* Three states need more room than two: hand narrow viewports one column
   (the reveal stepper walks them vertically just as well). */
@media (max-width: 1000px) {
   .iqv-mem[data-iqv-panels="3"] { grid-template-columns: 1fr; }
   /* stacked panels don't need alignment slots */
   .iqv-mem[data-iqv-panels="3"] .iqv-mvar.is-ghost { display: none; }
}

/* -- cycle: the ring --------------------------------------------------------
   Node/arrow positions are server-computed inline styles on a fixed-aspect
   square; the circle hairline passes behind the opaque cards. The vertical
   list fallback is rendered alongside and swapped in at the 700px break. */
.iqv-cycle-ring {
   position: relative;
   aspect-ratio: 1;
   max-width: 420px;
   margin: 0 auto;
}
.iqv-cycle-ring::before {
   content: "";
   position: absolute;
   inset: 10%; /* radius matches the renderer's R = 40% */
   border: 1.5px solid #B5B4AC;
   border-radius: 50%;
}
.iqv-cnode {
   background: var(--iq-card);
   border: 1.5px solid var(--iq-cardEdge);
   border-radius: 8px;
   padding: 7px 11px;
   text-align: center;
   max-width: 128px;
}
.iqv-cycle-ring .iqv-cnode {
   position: absolute;
   transform: translate(-50%, -50%);
   z-index: 1;
}
.iqv-cnode-label {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12.5px;
   font-weight: 400;
   color: var(--iq-ink);
}
.iqv-cnode-note {
   display: block;
   font-size: 10.5px;
   color: var(--iq-ink3);
   margin-top: 1px;
}
.iqv-cyclewrap[data-iqv-n="7"] .iqv-cycle-ring .iqv-cnode,
.iqv-cyclewrap[data-iqv-n="8"] .iqv-cycle-ring .iqv-cnode { max-width: 100px; padding: 5px 8px; }
.iqv-cyclewrap[data-iqv-n="7"] .iqv-cycle-ring .iqv-cnode-label,
.iqv-cyclewrap[data-iqv-n="8"] .iqv-cycle-ring .iqv-cnode-label { font-size: 11.5px; }
.iqv-cycle-arrow {
   position: absolute;
   width: 0;
   height: 0;
   border-top: 4.5px solid transparent;
   border-bottom: 4.5px solid transparent;
   border-left: 8px solid var(--iq-ink4);
}
.iqv-cycle-center {
   position: absolute;
   left: 50%;
   top: 50%;
   transform: translate(-50%, -50%);
   max-width: 46%;
   text-align: center;
   font-family: 'Instrument Sans', system-ui, sans-serif; letter-spacing: -0.035em; font-weight: 600;
   font-style: normal;
   font-size: 12.5px;
   color: var(--iq-ink3);
}
.iqv-cycle-list { display: none; }
.iqv-cycle-return {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11px;
   color: var(--iq-ink3);
   background: #F8F7F4;
   border: 1px solid var(--iq-divider);
   border-radius: 99px;
   padding: 2px 10px;
   margin-top: 8px;
}

/* -- flow: guard ladder ------------------------------------------------------
   Every row is a grid with the SAME fixed template, so the check spine
   (column 1) stays aligned whether the row holds a check, a drop, the start
   pill, or the else landing. Fully static. */
.iqv-flowwrap { display: flex; flex-direction: column; padding: 2px 0; }
.iqv-fgrid {
   display: grid;
   grid-template-columns: minmax(0, 5fr) 66px minmax(0, 4fr);
   align-items: center;
}
.iqv-fstart,
.iqv-fdrop { grid-column: 1; justify-self: center; }
.iqv-felserow .iqv-fout { grid-column: 1; justify-self: center; }
.iqv-fstart {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11px;
   color: var(--iq-ink3);
   background: #F8F7F4;
   border: 1px solid var(--iq-divider);
   border-radius: 99px;
   padding: 2px 10px;
}
.iqv-fcheck {
   grid-column: 1;
   justify-self: stretch;
   min-width: 0;
   background: var(--iq-card);
   border: 1.5px solid var(--iq-cardEdge);
   border-radius: 8px;
   padding: 9px 16px;
   text-align: center;
}
.iqv-feyebrow {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 9.5px;
   font-weight: 400;
   letter-spacing: 0.14em;
   text-transform: uppercase;
   color: var(--iq-ink4);
   margin-bottom: 1px;
}
.iqv-ftest {
   display: block;
   font-size: 13.5px;
   font-weight: 500;
   color: var(--iq-ink);
}
.iqv-fbranch { grid-column: 2; padding: 0 10px; }
.iqv-fbranch .iqv-conn-line { width: 46px; }
.iqv-fout {
   grid-column: 3;
   justify-self: start;
   min-width: 0;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 8px;
   padding: 8px 14px;
}
.iqv-fout .iqv-feyebrow { color: var(--iq-accentD); }
.iqv-fout-label {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12.5px;
   font-weight: 400;
   color: var(--iq-ink);
}
.iqv-fout small {
   display: block;
   font-size: 11px;
   color: var(--iq-ink3);
   margin-top: 1px;
}
.iqv-fdrop { display: flex; align-items: center; gap: 7px; padding: 3px 0; }
.iqv-fdrop-line {
   position: relative;
   display: block;
   width: 1.5px;
   height: 26px;
   background: #B5B4AC;
}
.iqv-fdrop-line::after {
   content: "";
   position: absolute;
   bottom: -1px;
   left: -3.25px;
   border-top: 7px solid #B5B4AC;
   border-left: 4px solid transparent;
   border-right: 4px solid transparent;
}
.iqv-fdrop-word {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10.5px;
   color: var(--iq-ink3);
}

/* -- tree: hierarchy ---------------------------------------------------------
   Classic connector tree: half-rulings and drops drawn by li pseudo-elements,
   parent stubs by nested ul::before. Scrolls horizontally on overflow. */
.iqv-tree-scroll { text-align: center; }
.iqv-treewrap {
   display: inline-block;
   min-width: max-content;
   padding: 6px 4px 2px;
}
.iqv-tree-ul {
   display: flex;
   justify-content: center;
   list-style: none;
   margin: 0;
   padding: 0;
   position: relative;
}
.iqv-tree-ul .iqv-tree-ul { padding-top: 18px; }
.iqv-tree-ul .iqv-tree-ul::before {
   content: "";
   position: absolute;
   top: 0;
   left: 50%;
   width: 0;
   height: 18px;
   border-left: 1px solid #B5B4AC;
}
.iqv-tree-li {
   display: flex;
   flex-direction: column;
   align-items: center;
   position: relative;
   padding: 18px 7px 0;
}
.iqv-tree-li::before,
.iqv-tree-li::after {
   content: "";
   position: absolute;
   top: 0;
   right: 50%;
   width: 50%;
   height: 18px;
   border-top: 1px solid #B5B4AC;
}
.iqv-tree-li::after {
   right: auto;
   left: 50%;
   border-left: 1px solid #B5B4AC;
}
.iqv-tree-li:only-child { padding-top: 0; }
.iqv-tree-li:only-child::before,
.iqv-tree-li:only-child::after { display: none; }
.iqv-tree-ul .iqv-tree-ul .iqv-tree-li:only-child { padding-top: 0; }
.iqv-tree-li:first-child::before { border-top: 0 none; }
.iqv-tree-li:last-child::after { border-top: 0 none; border-left: 0 none; }
.iqv-tree-li:last-child::before { border-right: 1px solid #B5B4AC; border-radius: 0 6px 0 0; }
.iqv-tree-li:first-child::after { border-radius: 6px 0 0 0; }
.iqv-tnode {
   background: var(--iq-card);
   border: 1.5px solid var(--iq-cardEdge);
   border-radius: 8px;
   padding: 8px 13px;
   text-align: center;
   /* Wide enough for a dotted full name (MyCompany.DataAccess.Xyz) on one
      line when the canvas has room; the box still shrinks to content, and
      anything longer wraps (see the overflow-wrap guard below) instead of
      spilling past the border. */
   max-width: 280px;
}
/* Long unbreakable tokens (dotted type names, URLs, snake_case) must wrap
   inside node cards - dots and underscores create no natural break points,
   so without this the token overflows the card border. Scoped to card
   text, never code blocks (.iqv-code scrolls by design). */
.iqv-tnode-label, .iqv-tnode-note,
.iqv-snode-label, .iqv-snode-note,
.iqv-cnode-label, .iqv-cnode-note,
.iqv-cbox-title, .iqv-cbox-note {
   overflow-wrap: anywhere;
   word-break: break-word;
}
.iqv-tnode-label {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12.5px;
   font-weight: 400;
   color: var(--iq-ink);
}
.iqv-tnode-note {
   display: block;
   font-size: 10.5px;
   color: var(--iq-ink3);
   margin-top: 1px;
}

/* -- anatomy: annotated code -------------------------------------------------
   Reuses trace's dark code block (.iqv-code/.iqv-cl/.iqv-ln, including the
   .is-hot line highlight); adds numbered badges and a legend of buttons. */
.iqv-anatomy-grid {
   display: grid;
   grid-template-columns: minmax(0, 11fr) minmax(0, 8fr);
   gap: 18px;
   align-items: start;
}
/* Refactor pair: the violating snippet beside the fixed one. Panels stack at
   the 700px break; the legend below serves both (badge numbering continues
   across panels, line ids are "b"-prefixed on the before side). */
.iqv-anatomy-pair {
   display: grid;
   grid-template-columns: repeat(2, minmax(0, 1fr));
   gap: 10px;
   min-width: 0;
}
/* A pair needs the WHOLE plate width, so the legend drops below it - which is
   what the comment above always described, but which only happened under the
   700px break. With the side legend taking 8fr, a pair's two panels landed at
   ~283px each even on a 1440px screen, while the schema lets a code line run
   to 70 characters (~510px). Every paired figure therefore clipped its code
   behind a scrollbar on desktop and read correctly only on mobile, where the
   pair already stacked. Measured: 283px panels -> ~500px, clipping gone. */
.iqv-anatomy-grid:has(.iqv-anatomy-pair) {
   grid-template-columns: minmax(0, 1fr);
}
/* Below ~1000px even the full-width pair leaves panels too narrow for a long
   line, so stack them here rather than at the 700px break the rest of the
   plate uses - two clipped snippets teach less than two stacked ones. */
@media (max-width: 1000px) {
   .iqv-anatomy-pair { grid-template-columns: minmax(0, 1fr); }
}
.iqv-apanel {
   min-width: 0;
   display: flex;
   flex-direction: column;
   gap: 6px;
}
/* .iqv-code's align-self:start sizes it to its longest line, which overflows
   the half-width panels — stretch it here so long lines scroll inside. */
.iqv-apanel > .iqv-code { align-self: stretch; }
.iqv-apanel-eyebrow {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   font-weight: 400;
   letter-spacing: 0.14em;
   text-transform: uppercase;
}
.iqv-apanel.is-before .iqv-apanel-eyebrow { color: var(--iq-rose); }
.iqv-apanel.is-after .iqv-apanel-eyebrow { color: var(--iq-green); }
/* Gutter slot beside the line number — present on every line (possibly
   empty) so the code's left edge stays aligned. */
.iqv-anno-badges {
   display: inline-flex;
   align-items: center;
   gap: 3px;
   min-width: 17px;
   flex-shrink: 0;
   align-self: center;
   margin-left: -4px;
}
.iqv-anno-badge {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   width: 15px;
   height: 15px;
   border-radius: 50%;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 9.5px;
   font-weight: 400;
   background: var(--iq-accent);
   color: #F8F7F4;
   flex-shrink: 0;
}
.iqv-anno-legend { list-style: none; margin: 0; padding: 0; }
.iqv-anno-legend li { margin: 0; border-bottom: 1px solid var(--iq-divider); }
.iqv-anno-legend li:last-child { border-bottom: 0; }
.iqv-anno {
   display: flex;
   gap: 10px;
   align-items: flex-start;
   width: 100%;
   text-align: left;
   background: none;
   border: 0;
   border-left: 2px solid transparent;
   padding: 9px 8px;
   cursor: pointer;
   font: inherit;
   transition: border-color .15s ease, background .15s ease;
}
.iqv-anno .iqv-anno-badge {
   background: var(--iq-card);
   color: var(--iq-accentD);
   border: 1.5px solid var(--iq-accentE);
   margin-top: 1px;
}
.iqv-anno.is-on,
.iqv-anno.is-lit {
   border-left-color: var(--iq-accent);
   background: rgba(229, 90, 18, 0.05);
}
.iqv-anno:focus-visible { outline: 2px solid var(--iq-accent); outline-offset: 1px; }
.iqv-anno-body { min-width: 0; }
.iqv-anno-label {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   font-weight: 400;
   color: var(--iq-ink);
}
.iqv-anno-text {
   display: block;
   font-size: 12.5px;
   line-height: 1.5;
   color: var(--iq-ink2);
   margin-top: 1px;
}

/* -- venn: two sets, one lens ------------------------------------------------
   Not real circle lenses (fragile with text) — two stadium-half cards
   bridged by a raised, overlapping "both" card. Fully static. */
.iqv-vennwrap {
   display: grid;
   grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
   align-items: stretch;
   padding: 6px 0 2px;
}
.iqv-vzone {
   background: var(--iq-card);
   border: 1.5px solid var(--iq-cardEdge);
   padding: 14px 18px;
   min-width: 0;
}
.iqv-vzone-a { border-radius: 26px 10px 10px 26px; }
.iqv-vzone-b { border-radius: 10px 26px 26px 10px; }
.iqv-vzone-shared {
   position: relative;
   z-index: 1;
   margin: 12px -17px;
   max-width: 250px;
   border-radius: 12px;
   border-color: var(--iq-accentE);
   background: var(--iq-accentS);
   box-shadow: 0 2px 10px rgba(35,35,32, 0.07);
}
.iqv-vzone-label {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 13px;
   font-weight: 400;
   color: var(--iq-ink);
   margin-bottom: 7px;
}
.iqv-vzone-eyebrow {
   display: flex;
   align-items: center;
   gap: 6px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   font-weight: 400;
   letter-spacing: 0.14em;
   text-transform: uppercase;
   color: var(--iq-accentD);
   margin-bottom: 7px;
}
.iqv-vzone-eyebrow i { font-style: normal; font-size: 13px; }
.iqv-vitems { list-style: none; margin: 0; padding: 0; }
.iqv-vitems li {
   margin: 0;
   position: relative;
   padding: 3px 0 3px 12px;
   font-size: 12.5px;
   line-height: 1.5;
   color: var(--iq-ink2);
}
.iqv-vitems li::before {
   content: "·";
   position: absolute;
   left: 0;
   color: var(--iq-ink4);
   font-weight: 700;
}
.iqv-vverdict {
   margin-top: 16px;
   padding-top: 12px;
   border-top: 2px solid var(--iq-ink);
   font-size: 13.5px;
   color: var(--iq-ink);
}
.iqv-vverdict b {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   font-weight: 400;
   letter-spacing: 0.14em;
   text-transform: uppercase;
   color: var(--iq-accentD);
   margin-bottom: 2px;
}

/* -- system: parts and connections in space ---------------------------------
   Reuses the states machinery wholesale (columns, gaps, connectors, honest
   list, mobile stacking); the only new furniture is the group container and
   the async/data connector-line variants. */
.iqv-sysgroup {
   display: flex;
   flex-direction: column;
   gap: 10px;
   border: 1px solid var(--iq-divider);
   border-radius: 10px;
   padding: 10px 12px;
   background: rgba(35,35,32, 0.025);
}
.iqv-sysgroup > .iqv-lane-head {
   margin-bottom: 0;
   justify-content: center;
}
/* async = dashed, data = dotted; the line becomes a 0-height border so the
   arrowhead re-centers via the adjusted top offset. Hover overrides keep the
   background transparent and recolor the border instead. */
.iqv-conn.is-async .iqv-conn-line,
.iqv-conn.is-data .iqv-conn-line {
   height: 0;
   background: none;
   border-top: 1.5px dashed #B5B4AC;
}
.iqv-conn.is-data .iqv-conn-line { border-top-style: dotted; }
.iqv-conn.is-async .iqv-conn-line::after,
.iqv-conn.is-data .iqv-conn-line::after { top: -4px; }
.iqv-conn.is-async.is-hot .iqv-conn-line,
.iqv-conn.is-data.is-hot .iqv-conn-line {
   background: none;
   border-top-color: var(--iq-accent);
}

/* -- pipeline: the data thread ----------------------------------------------
   Dark payload chips (the data) alternate with stage cards (the machinery).
   Each gap holds BOTH a horizontal arrow and a vertical drop; CSS shows one
   per breakpoint, so the mobile stack needs no rotation or measuring. */
.iqv-pipewrap {
   display: flex;
   align-items: center;
   width: max-content;
   max-width: none;
   margin: 0 auto;
   padding: 6px 0 2px;
}
.iqv-pstage {
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 8px;
   padding: 7px 14px 8px;
   text-align: center;
   flex-shrink: 0;
   max-width: 210px;
}
.iqv-pstage .iqv-feyebrow { margin-bottom: 0; }
.iqv-pstage-label {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12.5px;
   font-weight: 400;
   color: var(--iq-ink);
}
.iqv-pstage-note {
   display: block;
   font-size: 11px;
   color: var(--iq-ink3);
   margin-top: 1px;
}
.iqv-pchip {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   background: #2A2A26;
   color: #DFDDD7;
   border-radius: 6px;
   padding: 4px 10px;
   white-space: nowrap;
   flex-shrink: 0;
   max-width: 240px;
   overflow: hidden;
   text-overflow: ellipsis;
}
.iqv-pgap {
   display: flex;
   align-items: center;
   padding: 0 7px;
   flex-shrink: 0;
}
.iqv-pgap .iqv-conn-line { width: 30px; }
.iqv-pgap .iqv-fdrop-line { display: none; }

/* -- timeline: duration and overlap on a shared clock -----------------------
   One explicitly-placed grid (renderer inline styles): column 1 = lane
   labels, then N equal unit tracks (count mirrored in --iqv-tln for the
   mobile override). Bars stay proportional at any width. */
.iqv-tlwrap {
   display: grid;
   row-gap: 7px;
   align-items: stretch;
   padding: 4px 0 2px;
}
.iqv-tllane {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   font-weight: 400;
   letter-spacing: 0.14em;
   text-transform: uppercase;
   color: var(--iq-ink3);
   align-self: center;
   text-align: right;
   padding-right: 12px;
   white-space: nowrap;
   min-width: 0;
   overflow: hidden;
   text-overflow: ellipsis; /* the label track caps at fit-content(110px) */
}
.iqv-tlspan {
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 6px;
   padding: 4px 9px;
   min-width: 0;
   overflow: hidden;
}
.iqv-tlspan-label {
   display: block;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   color: var(--iq-ink);
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
}
/* Zero-width so the pin straddles its grid line; the end-clamped variant
   right-aligns instead (a pin at the final line would mint a phantom track). */
.iqv-tlev {
   width: 0;
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-self: start;
   overflow: visible;
}
.iqv-tlev.is-end {
   justify-self: end;
   align-items: flex-end;
}
.iqv-tlev.is-alt .iqv-tlev-label { margin-top: 13px; }
.iqv-tlev-pin {
   display: block;
   width: 1.5px;
   height: 12px;
   background: #B5B4AC;
   flex-shrink: 0;
}
.iqv-tlev-label {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   color: var(--iq-ink3);
   white-space: nowrap;
   margin-top: 2px;
}
.iqv-tlaxis {
   display: block;
   height: 0;
   border-top: 1px solid var(--iq-divider);
   align-self: start;
   margin-top: 2px;
}
.iqv-tltick {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   color: var(--iq-ink4);
   padding-top: 7px;
   white-space: nowrap;
   justify-self: start;
   transform: translateX(-50%);
}
.iqv-tltick.is-first { transform: none; }
.iqv-tltick.is-last {
   justify-self: end;
   transform: none;
}

@media (max-width: 700px) {
   .iqv-plate { padding: 14px 16px 16px; }
   .iqv-trace-grid { grid-template-columns: 1fr; }
   .iqv-stateswrap { flex-direction: column; align-items: stretch; }
   .iqv-scol { align-items: center; }
   .iqv-sgap { flex-direction: row; flex-wrap: wrap; justify-content: center; padding: 10px 0; }
   .iqv-stateswrap .iqv-conn { transform: rotate(90deg); }
   /* sequence: fr columns already compress — just shrink the type */
   .iqv-actor { padding: 5px 8px; font-size: 11px; }
   .iqv-msg-label { font-size: 10px; }
   /* memory: before/after panels stack; alignment slots become noise */
   .iqv-mem[data-iqv-panels="2"] { grid-template-columns: 1fr; }
   .iqv-mem .iqv-mvar.is-ghost { display: none; }
   /* cycle: swap the ring for the server-rendered vertical loop list */
   .iqv-cycle-ring { display: none; }
   .iqv-cycle-list { display: flex; flex-direction: column; align-items: center; }
   /* flow: single column; the branch arm becomes a "↳ yes" corner motif */
   .iqv-fgrid { grid-template-columns: 1fr; }
   .iqv-fbranch { grid-column: 1; flex-direction: row; justify-self: start; margin: 6px 0 2px 20px; padding: 0; }
   .iqv-fbranch .iqv-conn-line { display: none; }
   .iqv-fbranch .iqv-conn-label::before { content: "↳ "; color: var(--iq-ink4); }
   .iqv-frow .iqv-fout { grid-column: 1; justify-self: start; margin-left: 34px; }
   /* tree: tighten; the wrapper already scrolls horizontally */
   .iqv-tree-li { padding: 14px 4px 0; }
   .iqv-tnode { padding: 6px 9px; max-width: 150px; }
   /* anatomy: code above legend; refactor pair stacks */
   .iqv-anatomy-grid { grid-template-columns: 1fr; }
   .iqv-anatomy-pair { grid-template-columns: 1fr; }
   /* system: stacked columns inherit states' rules; cap group width */
   .iqv-syswrap .iqv-sysgroup { width: 100%; max-width: 320px; }
   /* pipeline: vertical stack — gaps swap their arrow for the drop */
   .iqv-pipewrap { flex-direction: column; width: 100%; }
   .iqv-pgap { padding: 5px 0; }
   .iqv-pgap .iqv-conn-line { display: none; }
   .iqv-pgap .iqv-fdrop-line { display: block; }
   .iqv-pchip {
      white-space: normal;
      word-break: break-word;
      text-align: center;
      max-width: 260px;
   }
   /* timeline: narrower label column (track count mirrored in --iqv-tln) */
   .iqv-tlwrap {
      grid-template-columns: fit-content(70px) repeat(var(--iqv-tln), minmax(0, 1fr)) !important;
      row-gap: 5px;
   }
   .iqv-tllane { font-size: 9px; padding-right: 8px; white-space: normal; }
   .iqv-tlspan { padding: 3px 6px; }
   .iqv-tlspan-label { font-size: 10.5px; }
   .iqv-tltick, .iqv-tlev-label { font-size: 9px; }
   /* venn: zones stack; the "both" card bridges them vertically */
   .iqv-vennwrap { grid-template-columns: 1fr; }
   .iqv-vzone-a { border-radius: 26px 26px 10px 10px; }
   .iqv-vzone-b { border-radius: 10px 10px 26px 26px; }
   .iqv-vzone-shared { margin: -14px 24px; max-width: none; }
}
@media (prefers-reduced-motion: reduce) {
   .iqv *, .iqv { transition: none !important; animation: none !important; }
}

/* ---------- Reveal mode + fullscreen (iqv additions) ---------- */
/* Stage engine (iqv-interactions.js): elements past the current stage dim to
   a skeleton; the current stage gets a soft accent ring. Server HTML never
   carries these classes — no-JS/print/reduced-motion keep the full figure. */
.iqv-veiled { opacity: 0.22; transition: opacity 0.25s ease; }

/* Per-question focus on a SHARED concept figure (iqv-interactions applyFocus).
   A concept figure serves every question that links it, so `is-focus` marks the
   parts THIS question is about. Deliberately gentler than .iqv-veiled: the rest
   of the figure is context the reader still needs, not a future stage. The
   class is distinct from is-hot, which the hover/pin handlers own and rewrite
   on every pointer move. Server HTML never carries either class. */
.iqv.has-focus [data-iqv-node]:not(.is-focus),
.iqv.has-focus [data-iqv-line]:not(.is-focus),
.iqv.has-focus [data-iqv-msg]:not(.is-focus),
.iqv.has-focus [data-iqv-obj]:not(.is-focus),
.iqv.has-focus [data-iqv-box]:not(.is-focus) {
   opacity: 0.5;
   transition: opacity 0.25s ease;
}
.iqv .is-focus {
   box-shadow: 0 0 0 2px var(--iq-accent);
   border-radius: 4px;
}
.iqv.is-armed .iqv-snode.is-now,
.iqv.is-armed .iqv-cnode.is-now,
.iqv.is-armed .iqv-tnode.is-now,
.iqv.is-armed .iqv-pstage.is-now,
.iqv.is-armed .iqv-frow.is-now .iqv-fcheck,
.iqv.is-armed li.is-now .iqv-anno {
   /* rgba of var(--iq-accent) #E55A12 */
   box-shadow: 0 0 0 2px rgba(229, 90, 18, 0.35);
   border-radius: 8px;
}
.iqv.is-armed .iqv-frow.is-now .iqv-conn-line { background: var(--iq-accent); }
.iqv.is-armed .iqv-frow.is-now .iqv-conn-line::after { border-left-color: var(--iq-accent); }
/* memory panels, system groups, pipeline chips and timeline bars keep their
   own border radii, so they ring without the shared border-radius. */
.iqv.is-armed .iqv-mpanel.is-now,
.iqv.is-armed .iqv-sysgroup.is-now,
.iqv.is-armed .iqv-pchip.is-now,
.iqv.is-armed .iqv-tlspan.is-now { box-shadow: 0 0 0 2px rgba(229, 90, 18, 0.35); }
/* system connectors ring like flow's when their stage is current */
.iqv.is-armed .iqv-conn.is-now .iqv-conn-line { background: var(--iq-accent); }
.iqv.is-armed .iqv-conn.is-now .iqv-conn-line::after { border-left-color: var(--iq-accent); }
.iqv.is-armed .iqv-conn.is-async.is-now .iqv-conn-line,
.iqv.is-armed .iqv-conn.is-data.is-now .iqv-conn-line {
   background: none;
   border-top-color: var(--iq-accent);
}
.iqv.is-armed .iqv-conn.is-now .iqv-conn-label { color: var(--iq-accentD); }
/* timeline event pins light with their stage */
.iqv.is-armed .iqv-tlev.is-now .iqv-tlev-pin { background: var(--iq-accent); }
.iqv.is-armed .iqv-tlev.is-now .iqv-tlev-label { color: var(--iq-accentD); }
/* Chrome ships with the `hidden` attribute; keep it hidden even if another
   display rule ever matches the wrapper. */
.iqv-revealchrome[hidden] { display: none !important; }

/* Show all — reveal chrome only: skip the walk (overview-first readers,
   returning visitors). Quieter than Prev/Next. */
.iqv-showall { font-weight: 500; color: var(--iq-ink3); }
.iqv-showall:hover:not(:disabled) { color: var(--iq-ink); }

/* Predict mode (trace): active-recall pause before each reveal. The toggle is
   client-injected into the stepbar (iqv-interactions.js). */
.iqv-predict.is-on { border-color: var(--iq-accent); color: var(--iq-accentD); }
.iqv.is-predicting .iqv-narr p { color: var(--iq-accentD); font-style: italic; }

/* comparison rows + venn zones joined reveal mode: current-stage affordance */
.iqv.is-armed tr.is-now th,
.iqv.is-armed tr.is-now td { background: rgba(229, 90, 18, 0.06); }
.iqv.is-armed .iqv-vzone.is-now { box-shadow: 0 0 0 2px rgba(229, 90, 18, 0.35); }

/* states/system: tap-pinned node (the touch path for hover) */
.iqv-snode.is-pinned { outline: 2px solid rgba(229, 90, 18, 0.5); outline-offset: 1px; }

/* Touch: stepper controls need real tap targets */
@media (pointer: coarse) {
   .iqv-stepbtn { padding: 10px 16px; min-height: 44px; }
}

/* Expand control — lives in the plate head, right-aligned even with no title. */
.iqv-expand {
   margin-left: auto;
   align-self: center;
   display: inline-flex;
   align-items: center;
   justify-content: center;
   width: 26px;
   height: 26px;
   padding: 0;
   border: 1px solid var(--iq-rule);
   border-radius: 7px;
   background: transparent;
   color: var(--iq-ink3);
   cursor: pointer;
}
.iqv-expand:hover { color: var(--iq-accent); border-color: var(--iq-accent); }
.iqv-expand:focus-visible { outline: 2px solid var(--iq-accent); outline-offset: 1px; }

/* Copy-code (trace/anatomy) — lives beside the expand control in the plate
   head. Served with the `hidden` attribute; iqv-interactions.js unhides it
   when the clipboard API exists, so image pipelines and no-JS pages never
   show it. */
.iqv-copy {
   margin-left: auto;
   height: 26px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10.5px;
   letter-spacing: 0.06em;
   color: var(--iq-ink3);
   background: transparent;
   border: 1px solid var(--iq-rule);
   border-radius: 7px;
   padding: 0 9px;
   cursor: pointer;
}
.iqv-copy:hover { color: var(--iq-accent); border-color: var(--iq-accent); }
.iqv-copy:focus-visible { outline: 2px solid var(--iq-accent); outline-offset: 1px; }
/* Only a VISIBLE copy button takes over the auto push — while it ships
   `hidden` (no-JS, clipboard-less browsers, image pipelines) the expand
   control must keep right-aligning itself. */
.iqv-copy:not([hidden]) + .iqv-expand { margin-left: 8px; }
/* Clipped board (iqv-interactions.js watchOverflow): the icon-only button is
   easy to miss, and the right-edge fade reads as styling rather than "there is
   more". Name the way out. Width is auto here, so the 26px square relaxes into
   a labelled pill only while it is needed. */
.iqv-plate.is-clipped .iqv-expand {
   width: auto;
   gap: 6px;
   padding: 0 9px;
   border-color: var(--iq-accent);
   color: var(--iq-accent);
}
.iqv-plate.is-clipped .iqv-expand::after {
   content: 'Expand';
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 10px;
   letter-spacing: .08em;
   text-transform: uppercase;
}
.iqv-plate.is-fullscreen .iqv-expand::after { content: none; }

/* Fullscreen overlay — the LIVE plate node moves in (state survives), so all
   delegated handlers keep working. Pinch-zoom stays native page zoom. */
.iqv-overlay {
   position: fixed;
   inset: 0;
   z-index: 200;
   background: rgba(24, 18, 12, 0.55);
   overflow: auto;
   -webkit-overflow-scrolling: touch;
   padding: 20px 16px calc(24px + env(safe-area-inset-bottom));
}
.iqv-overlay-close {
   position: fixed;
   top: 12px;
   right: 14px;
   z-index: 1;
   width: 36px;
   height: 36px;
   border-radius: 50%;
   border: 1px solid var(--iq-rule);
   background: #F8F7F4;
   color: var(--iq-ink2);
   font-size: 22px;
   line-height: 1;
   cursor: pointer;
}
.iqv-overlay-close:hover { color: var(--iq-accent); border-color: var(--iq-accent); }
.iqv-overlay-close:focus-visible { outline: 2px solid var(--iq-accent); outline-offset: 1px; }
.iqv-plate.is-fullscreen {
   width: min(1100px, 100%);
   margin: 44px auto;
   box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
}
/* On large screens "expand" must MAGNIFY, not just re-frame: inline plates in
   wide layouts already exceed 1100px, and stretching a grid wider doesn't make
   it more readable — scaling it up does. zoom scales layout+type together;
   pre-zoom widths are chosen so the rendered plate fits the viewport tier.
   (Browsers without css zoom just get the wider un-magnified plate.) */
/* Each breakpoint must EXCEED the zoomed width + the overlay's 32px side
   padding, or the plate overflows and pins left-flush (1280/1366 laptops sat
   in exactly that broken band when this fired at 1200px). */
@media (min-width: 1440px) {
   .iqv-plate.is-fullscreen { width: 1100px; zoom: 1.25; } /* renders ~1375px */
}
@media (min-width: 1800px) {
   .iqv-plate.is-fullscreen { width: 1240px; zoom: 1.4; } /* renders ~1736px */
}
/* Already expanded — the in-plate expand control is meaningless here. */
.iqv-plate.is-fullscreen .iqv-expand { display: none; }
/* Prev/Next stay thumb-reachable while a tall figure scrolls. */
.iqv-plate.is-fullscreen .iqv-stepbar {
   position: sticky;
   bottom: 0;
   background: #F8F7F4;
   padding-bottom: env(safe-area-inset-bottom);
}
html.iqv-lock { overflow: hidden; }

@media print {
   .iqv-veiled { opacity: 1 !important; }
   .iqv.has-focus [data-iqv-node], .iqv.has-focus [data-iqv-line],
   .iqv.has-focus [data-iqv-msg], .iqv.has-focus [data-iqv-obj],
   .iqv.has-focus [data-iqv-box] { opacity: 1 !important; }
   .iqv-expand, .iqv-revealchrome { display: none !important; }
   /* rails were measured against screen layout; badge pairs carry print */
   .iqv-mlinks { display: none !important; }
}

/* ==========================================================================
   TRANSIT SKIN — the figure as a line diagram on a signage board.
   Beck grammar: thick round-capped route lines in tone colors, station rings
   at junctions, an ink signage bar for the plate title. Nodes are stations;
   edges are the lines. Chosen over readout/press/blueprint in the 2026-07
   direction bake-off.

   This layer deliberately OVERRIDES the base .iqv-* rules above rather than
   editing them in place: base owns structure (grids, positioning, steppers,
   reveal, fullscreen), this layer owns the skin. Same single-class
   specificity — source order wins. The client-drawn route connectors for
   states/system live in public/js/iqv-connectors.js (.iqv-connsvg below);
   every other archetype gets the metro look from thickened CSS lines.
   ========================================================================== */
:root {
   --tr-ink: #1E1C18;      /* signage ink */
   --tr-ink2: #45433C;
   --tr-ink3: #5F5C55;
   --tr-board: #FBFBF8;    /* the enamel board */
   --tr-rule: #E3E1D9;
   --tr-dash: #B9B6AD;
}

/* -- Signage board plate ------------------------------------------------- */
.iqv-plate {
   background: var(--tr-board);
   border: 2px solid var(--tr-ink);
   border-radius: 16px;
   box-shadow: 0 10px 24px -14px rgba(30, 28, 24, .5);
   padding-top: 0;
   /* Readability bump over the base 1.08 — scales every archetype's
      hardcoded px type uniformly (2026-07-23, user ask). The connector
      engine and memory rails normalize zoom when measuring, and the
      fullscreen tiers set their own zoom. */
   zoom: 1.16;
}
.iqv-plate::before,
.iqv-plate-mark { color: rgba(30, 28, 24, .35); }
/* The tiled diagonal imprint (base .iqv-plate::after) is LIVE on this skin.
   It was retired here 2026-07-23 with a display:none kill switch; re-enabled
   2026-08-01 (user ask: screenshots must carry the mark) with the sparser,
   fainter tuning in the base rule. To retire again, restore
   `.iqv-plate::after { display: none; }` at this spot - source order wins. */

/* Head becomes the ink signage bar. Negative margins mirror the plate's side
   padding (18px 22px base, 14px 16px under 700px). */
.iqv-plate-head {
   background: var(--tr-ink);
   margin: 0 -22px 20px;
   padding: 13px 22px;
   border-radius: 13px 13px 0 0;
   border-bottom: 0;
   align-items: center;
}
.iqv-plate-title {
   color: #FFFFFF;
   font-weight: 700;
   font-size: 15.5px;
   letter-spacing: -.01em;
   display: flex;
   align-items: center;
   gap: 10px;
}
/* The line roundel — the mark of the system. */
.iqv-plate-title::before {
   content: '';
   width: 13px;
   height: 13px;
   border-radius: 50%;
   background: var(--iq-accent);
   box-shadow: 0 0 0 2.5px #fff;
   flex: none;
}
.iqv-expand {
   background: transparent;
   border: 1.5px solid rgba(255, 255, 255, .45);
   color: #fff;
   border-radius: 8px;
}
.iqv-expand:hover { color: #fff; border-color: #fff; }
.iqv-caption { color: var(--tr-ink2); font-weight: 600; }

/* -- Tone dots become line roundels -------------------------------------- */
.iqv-dot {
   width: 9px;
   height: 9px;
   background: #fff;
   border: 2.5px solid var(--tr-dash);
}
.iqv-dot-g { background: #fff; border-color: var(--iq-greenDot); }
.iqv-dot-a { background: #fff; border-color: var(--iq-amberDot); }
.iqv-dot-r { background: #fff; border-color: var(--iq-roseDot); }
.iqv-dot-acc { background: #fff; border-color: var(--iq-accent); }

/* -- Stations (every archetype's node card) ------------------------------- */
.iqv-snode, .iqv-cnode, .iqv-tnode, .iqv-cbox, .iqv-fcheck, .iqv-actor {
   background: #FFFFFF;
   border: 2.5px solid var(--tr-ink);
   border-radius: 12px;
   box-shadow: none;
}
.iqv-snode:hover { transform: none; box-shadow: 0 3px 0 -1px rgba(30, 28, 24, .25); }
.iqv-snode-label, .iqv-cnode-label, .iqv-tnode-label, .iqv-cbox-title { color: var(--tr-ink); }
.iqv-snode-note, .iqv-cnode-note, .iqv-tnode-note, .iqv-cbox-note { color: var(--tr-ink3); }
.iqv-fout, .iqv-pstage, .iqv-tlspan {
   background: #FFFFFF;
   border: 2px solid var(--tr-ink);
   border-radius: 10px;
}
.iqv-sysgroup {
   background: rgba(30, 28, 24, .04);
   border: 2px dashed var(--tr-dash);
   border-radius: 12px;
}
/* Zone tags: lane heads inside groups/panels read as service signs. */
.iqv-sysgroup > .iqv-lane-head span,
.iqv-mpanel-label {
   background: var(--tr-ink);
   color: #fff;
   padding: 3px 9px;
   border-radius: 5px;
   letter-spacing: .12em;
}
.iqv-mpanel-label { display: inline-block; }

/* -- Route lines: every CSS connector thickens to the metro stroke -------- */
.iqv-conn-line {
   height: 4px;
   border-radius: 999px;
   background: var(--tr-ink);
}
.iqv-conn-line::after {
   top: -3px;
   border-left: 8px solid var(--tr-ink);
   border-top: 5px solid transparent;
   border-bottom: 5px solid transparent;
}
.iqv-conn.is-async .iqv-conn-line,
.iqv-conn.is-data .iqv-conn-line {
   border-top: 4px dashed var(--tr-dash);
}
.iqv-conn.is-data .iqv-conn-line { border-top-style: dotted; border-top-color: var(--iq-greenDot); }
.iqv-conn.is-async .iqv-conn-line::after,
.iqv-conn.is-data .iqv-conn-line::after { top: -7px; }
.iqv-conn-label { color: var(--tr-ink2); font-weight: 400; }
.iqv-strans code { border-radius: 999px; border-color: var(--tr-ink); padding: 1px 8px; }
/* flow drop */
.iqv-fdrop-line { width: 4px; border-radius: 999px; background: var(--tr-ink); }
.iqv-fdrop-line::after {
   left: -3px;
   border-top: 8px solid var(--tr-ink);
   border-left: 5px solid transparent;
   border-right: 5px solid transparent;
}
/* chain spine */
.iqv-spine { width: 5px; margin-left: -2.5px; border-radius: 999px; background: var(--tr-rule); }
.iqv-spine-fill { width: 5px; margin-left: -2.5px; border-radius: 999px; }
/* tree rulings */
.iqv-tree-ul .iqv-tree-ul::before { border-left: 2.5px solid var(--tr-ink); }
.iqv-tree-li::before, .iqv-tree-li::after { border-top: 2.5px solid var(--tr-ink); height: 18px; }
.iqv-tree-li::after { border-left: 2.5px solid var(--tr-ink); }
.iqv-tree-li:last-child::before { border-right: 2.5px solid var(--tr-ink); border-radius: 0 10px 0 0; border-top: 2.5px solid var(--tr-ink); }
.iqv-tree-li:first-child::after { border-radius: 10px 0 0 0; }
.iqv-tree-li:first-child::before { border-top: 0 none; }
.iqv-tree-li:last-child:first-child::before { display: none; }
/* cycle ring */
.iqv-cycle-ring::before { border: 4.5px solid var(--tr-ink); }
.iqv-cycle-arrow {
   border-top: 6px solid transparent;
   border-bottom: 6px solid transparent;
   border-left: 10px solid var(--tr-ink);
}
/* sequence lifelines + messages */
.iqv-lifeline { border-left: 2.5px solid var(--tr-rule); }
.iqv-msg-line { border-top: 3.5px solid var(--tr-ink); }
.iqv-msg-line::after {
   top: -6.5px;
   border-top: 5px solid transparent;
   border-bottom: 5px solid transparent;
}
.iqv-msg.is-ltr .iqv-msg-line::after { border-left: 9px solid var(--tr-ink); }
.iqv-msg.is-rtl .iqv-msg-line::after { border-right: 9px solid var(--tr-ink); }
.iqv-msg.is-async .iqv-msg-line { border-top-style: dashed; border-top-color: var(--tr-ink); }
.iqv-msg.is-return .iqv-msg-line { border-top: 2px dashed var(--tr-dash); }
.iqv-msg.is-return .iqv-msg-line::after { top: -5.5px; }
.iqv-msg.is-return.is-ltr .iqv-msg-line::after { border-left-color: var(--tr-dash); }
.iqv-msg.is-return.is-rtl .iqv-msg-line::after { border-right-color: var(--tr-dash); }
.iqv-msg.is-now .iqv-msg-line { border-top-color: var(--iq-accent); }
.iqv-msg.is-now.is-ltr .iqv-msg-line::after { border-left-color: var(--iq-accent); }
.iqv-msg.is-now.is-rtl .iqv-msg-line::after { border-right-color: var(--iq-accent); }
.iqv-msg-label { background: var(--tr-board); font-weight: 500; }
/* memory rails (client-drawn SVG) become route lines with station ends */
.iqv-mlink path { stroke: var(--tr-ink); stroke-width: 3; stroke-linecap: round; }
.iqv-mlink circle { fill: #fff; stroke: var(--tr-ink); stroke-width: 2.5; r: 4.5px; }
.iqv-mlink.is-hot path { stroke: var(--iq-accent); }
.iqv-mlink.is-hot circle { fill: #fff; stroke: var(--iq-accent); }
/* timeline */
.iqv-tlev-pin { width: 3px; border-radius: 999px; background: var(--tr-ink); height: 14px; }
.iqv-tlaxis { border-top: 2px solid var(--tr-rule); }

/* -- Small furniture: pills, chips, wells --------------------------------- */
.iqv-fstart, .iqv-cycle-return, .iqv-clink span {
   background: #fff;
   border: 1.5px solid var(--tr-ink);
   border-radius: 999px;
   color: var(--tr-ink2);
}
.iqv-probe {
   border: 2px solid var(--tr-ink);
   border-radius: 999px;
   background: #fff;
   font-weight: 500;
}
.iqv-probe:hover { border-color: var(--tr-ink); background: var(--tr-rule); }
.iqv-probe.is-on { background: var(--tr-ink); border-color: var(--tr-ink); color: #fff; }
.iqv-cbox.is-lit { border-color: var(--iq-amberDot); background: #FDF6E5; }
.iqv-cbox.is-hit { border-color: var(--iq-greenDot); background: #EAF5EE; }
.iqv-tok {
   border: 2px solid var(--tr-ink);
   border-radius: 9px;
   background: #fff;
   box-shadow: none;
   color: var(--tr-ink);
}
.iqv-stackwell { border-bottom: 3px solid var(--tr-ink); }
.iqv-queuerow { border-bottom: 2px solid var(--tr-rule); }
.iqv-mcode { border: 1.5px solid var(--tr-ink); border-radius: 8px; background: #fff; }
.iqv-mobj { border: 2px solid var(--tr-ink); border-radius: 10px; background: #fff; }
.iqv-mobj.is-target { border-color: var(--iq-accent); box-shadow: none; }
.iqv-mrefbadge { border: 2px solid var(--tr-ink); background: #fff; color: var(--tr-ink); }
.iqv-mrefbadge.is-hot { border-color: var(--iq-accent); color: var(--iq-accentD); background: #fff; }
.iqv-mpanel { border: 1.5px solid var(--tr-rule); border-radius: 12px; }
.iqv-anno-badge { box-shadow: 0 0 0 2px #fff; }
.iqv-anno .iqv-anno-badge { background: #fff; border: 2px solid var(--iq-accent); color: var(--iq-accentD); box-shadow: none; }
.iqv-vzone { border: 2.5px solid var(--tr-ink); background: #fff; }
.iqv-vzone-shared { border-color: var(--iq-accent); background: #FDEFE4; box-shadow: none; }
.iqv-pchip { background: var(--tr-ink); border-radius: 999px; padding: 4px 12px; }

/* -- Comparison: fare-table signage --------------------------------------- */
.iqv-cmp thead th {
   font-family: 'Instrument Sans', sans-serif;
   font-weight: 700;
   font-size: 13.5px;
   background: var(--tr-ink);
   color: #fff;
   border-bottom: 0;
   padding: 10px 14px;
}
.iqv-cmp thead th:first-child { border-radius: 8px 0 0 8px; }
.iqv-cmp thead th:last-child { border-radius: 0 8px 8px 0; }
.iqv-cmp tbody th { color: var(--tr-ink3); border-bottom-color: var(--tr-rule); }
.iqv-cmp tbody td { border-bottom: 1.5px solid var(--tr-rule); color: var(--tr-ink2); }
.iqv-cmp td.iqv-gotcha {
   background: rgba(217, 160, 19, .14);
   border-radius: 0;
}
.iqv-cmp tfoot td { border-top: 2.5px solid var(--tr-ink); color: var(--tr-ink); }

/* -- Dark panels: code/console keep signage ink --------------------------- */
.iqv-code, .iqv-console { background: var(--tr-ink); border-radius: 12px; }
.iqv-cl { color: #C9C6BD; }
.iqv-cl.is-hot { background: rgba(229, 90, 18, .22); color: #fff; }

/* -- Stepper: platform controls ------------------------------------------- */
.iqv-stepnum {
   background: var(--tr-ink);
   color: #fff;
   border-radius: 9px;
   font-size: 16px;
   padding: 5px 9px 6px;
   min-width: 36px;
}
.iqv-stepnum small { color: rgba(255, 255, 255, .6); }
.iqv-stepbtn {
   border: 2px solid var(--tr-ink);
   border-radius: 999px;
   background: #fff;
   font-weight: 700;
   color: var(--tr-ink);
}
.iqv-stepbtn:hover:not(:disabled) { background: var(--tr-ink); color: #fff; border-color: var(--tr-ink); }
.iqv-track { height: 5px; border-radius: 999px; background: var(--tr-rule); }
.iqv-track i { border-radius: 999px; }

/* -- Reveal: the "now" station gets a double-ring halo -------------------- */
.iqv.is-armed .iqv-snode.is-now,
.iqv.is-armed .iqv-cnode.is-now,
.iqv.is-armed .iqv-tnode.is-now,
.iqv.is-armed .iqv-pstage.is-now,
.iqv.is-armed .iqv-frow.is-now .iqv-fcheck,
.iqv.is-armed li.is-now .iqv-anno {
   box-shadow: 0 0 0 2.5px var(--tr-board), 0 0 0 5.5px var(--iq-accent);
   border-radius: 12px;
}
.iqv.is-armed .iqv-mpanel.is-now,
.iqv.is-armed .iqv-sysgroup.is-now,
.iqv.is-armed .iqv-pchip.is-now,
.iqv.is-armed .iqv-tlspan.is-now { box-shadow: 0 0 0 2.5px var(--tr-board), 0 0 0 5.5px var(--iq-accent); }

/* -- Client-drawn route connectors (iqv-connectors.js) -------------------- */
/* When the engine draws, the CSS fallback lines and the "honest list" of
   unroutable edges retire — every edge is now actually a line on the map. */
.iqv-conns-drawn .iqv-sgap .iqv-conn-line { visibility: hidden; }
/* The label goes further than `visibility: hidden` and leaves the flow
   entirely. It is `white-space: nowrap`, so a composed fallback string like
   "App Servers reads → Replicas" (≈280px) would keep sizing its lane long
   after the engine stopped showing it — a 10-node board then measures ~860px
   wide and gets clipped in the reading column, hiding whole tiers. Drawn lanes
   only need the 78px .iqv-conn-line. Same idea as the ≤700px rule below, which
   drops the whole .iqv-conn once the board stacks. */
.iqv-conns-drawn .iqv-sgap .iqv-conn-label { display: none; }
.iqv-conns-drawn .iqv-strans { display: none; }
svg.iqv-connsvg {
   position: absolute;
   inset: 0;
   overflow: visible;
   pointer-events: none;
   z-index: 2;
}
.iqv-conns-drawn .iqv-stateswrap { position: relative; }
svg.iqv-connsvg .iqv-connpath {
   stroke: var(--tr-ink);
   stroke-width: 4.5;
   stroke-linecap: round;
   fill: none;
}
svg.iqv-connsvg .is-async .iqv-connpath { stroke-dasharray: 8 7 !important; }
svg.iqv-connsvg .is-data .iqv-connpath { stroke: var(--iq-greenDot); stroke-dasharray: 0.1 9 !important; }
svg.iqv-connsvg .iqv-station {
   fill: #fff;
   stroke: var(--tr-ink);
   stroke-width: 2.5;
}
svg.iqv-connsvg .is-data .iqv-station { stroke: var(--iq-greenDot); }
svg.iqv-connsvg .is-hot .iqv-connpath,
svg.iqv-connsvg .is-now .iqv-connpath { stroke: var(--iq-accent); }
svg.iqv-connsvg .is-hot .iqv-station,
svg.iqv-connsvg .is-now .iqv-station { stroke: var(--iq-accent); }
svg.iqv-connsvg .iqv-connlabel {
   font-family: 'Instrument Sans', sans-serif;
   font-size: 10.5px;
   font-weight: 700;
   fill: var(--tr-ink);
   stroke: var(--tr-board);
   stroke-width: 4px;
   paint-order: stroke;
   stroke-linejoin: round;
}
svg.iqv-connsvg .is-hot .iqv-connlabel,
svg.iqv-connsvg .is-now .iqv-connlabel { fill: var(--iq-accent); }
/* Draw-in on reveal: solid routes draw themselves; dashed lines just fade.
   The engine sets --iqvPl to the measured path length per edge. */
svg.iqv-connsvg g[data-iqv-stage] .iqv-connpath { transition: stroke-dashoffset .55s ease; }
svg.iqv-connsvg g.is-sync[data-iqv-stage] .iqv-connpath {
   stroke-dasharray: var(--iqvPl, none);
   stroke-dashoffset: 0;
}
svg.iqv-connsvg g.is-sync.iqv-veiled .iqv-connpath { stroke-dashoffset: var(--iqvPl, 0); }

/* Titleless plates (some cached specs skip the title): the signage bar still
   caps the plate — give it the line roundel so it doesn't read as an empty
   black band. (:has is fine here; browsers without it just show the bar.) */
.iqv-plate-head:not(:has(.iqv-plate-title))::before {
   content: '';
   width: 13px;
   height: 13px;
   border-radius: 50%;
   background: var(--iq-accent);
   box-shadow: 0 0 0 2.5px #fff;
   flex: none;
}

/* -- Chrome bits that hardcoded the old paper ----------------------------- */
.iqv-overlay-close { background: var(--tr-board); border: 2px solid var(--tr-ink); color: var(--tr-ink); }
.iqv-plate.is-fullscreen .iqv-stepbar { background: var(--tr-board); }
@media (max-width: 700px) {
   .iqv-plate { padding-top: 0; }
   .iqv-plate-head { margin: 0 -16px 18px; padding: 12px 16px; border-radius: 13px 13px 0 0; }
   /* The base 700px rule rotates .iqv-conn for the stacked-column fallback —
      the engine's SVG <g> ALSO carries .iqv-conn (for hover delegation) but
      is drawn against the real stacked layout, so it must never rotate. */
   .iqv-stateswrap g.iqv-conn { transform: none; }
   /* Once routes are drawn, the stacked fallback conns are dead space (their
      hidden labels also mint phantom horizontal overflow) — collapse them and
      keep a modest gap for the routes to breathe. Desktop keeps visibility:
      there the sgap WIDTH holds the columns apart. */
   .iqv-conns-drawn .iqv-sgap .iqv-conn { display: none; }
   .iqv-conns-drawn .iqv-sgap { min-height: 26px; }
}

/* On-page visual section (single-question page, all visitors) */
.iq-visual-section { margin: 26px 0 0; }
.iq-visual-head {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 12px;
   flex-wrap: wrap;
   margin-bottom: 12px;
}
/* The bridge sentence on a concept figure: why THIS question is looking at a
   shared diagram. It is the primary focus mechanism - most archetypes expose
   no addressable parts at all - so it is styled to be read, above the figure,
   rather than as a footnote below it. */
.iq-visual-bridge {
   margin: 0 0 12px;
   padding: 10px 14px;
   font-size: 0.94rem;
   line-height: 1.55;
   color: var(--iq-ink2);
   background: var(--iq-card);
   border-left: 3px solid var(--iq-accent);
   border-radius: 0 6px 6px 0;
}
.iq-visual-license {
   margin: 8px 0 0;
   font-size: 0.72rem;
   color: var(--iq-ink4);
   display: flex;
   align-items: baseline;
   gap: 12px;
   flex-wrap: wrap;
}
/* margin-left:auto (not space-between) so the © notice stays right-aligned
   even when the report control isn't rendered (signed-out, already flagged). */
.iq-visual-license-text {
   margin-left: auto;
   text-align: right;
}
.iq-visual-cta {
   margin-top: 14px;
   padding: 14px 16px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 12px;
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 14px;
   flex-wrap: wrap;
}
.iq-visual-cta p { margin: 0; color: var(--iq-ink2); font-size: 0.92rem; }
.iq-visual-teaser-card {
   padding: 16px 18px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 12px;
   display: flex;
   align-items: center;
   gap: 14px;
   flex-wrap: wrap;
}
.iq-visual-teaser-text { flex: 1; min-width: 200px; }
.iq-visual-teaser-text p { margin: 0; }

/* ---------- Practice mode + mastery ---------- */
/* "Needs review" filter chip — reuses the difficulty-chip dot idiom, plus a
   live count. Hidden (x-show) until the topic has something to review. */
.iq-qchip-review { --dot: var(--iq-amberDot); }
.iq-qchip-count {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   font-weight: 400;
   line-height: 1;
   padding: 3px 7px;
   border-radius: 999px;
   background: var(--iq-amberS);
   color: var(--iq-amber);
}

/* Browse | Practice — a segmented mode control, deliberately NOT a chip: it
   changes how rows behave (attempt-first vs. read), not which rows show.
   Practice-active is loud (accent fill) so a persisted practice mode is
   obvious on return visits. */
.iq-mode {
   display: inline-flex;
   align-items: center;
   gap: 2px;
   padding: 4px;
   border-radius: 999px;
   background: var(--iq-paper2);
   border: 1px solid var(--iq-cardEdge);
   box-shadow: inset 0 1px 3px rgba(35,35,32,.1); /* switch housing */
   flex-shrink: 0;
}
.iq-mode-btn {
   appearance: none;
   border: 1px solid transparent;
   background: transparent;
   cursor: pointer;
   display: inline-flex;
   align-items: center;
   gap: 6px;
   padding: 5px 14px;
   border-radius: 999px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13.5px;
   font-weight: 600;
   color: var(--iq-ink4);
   transition: all .15s ease;
}
.iq-mode-btn:hover { color: var(--iq-ink2); }
.iq-mode-btn.is-on {
   background: linear-gradient(180deg, #FFFFFF, #F2F1EE); color: var(--iq-ink);
   border-color: transparent;
   box-shadow: 0 1px 3px rgba(35,35,32,.2), 0 1px 0 rgba(255,255,255,.9) inset; /* raised knob */
}
.iq-mode-btn.iq-mode-practice.is-on {
   background: linear-gradient(180deg, #F06A24, var(--iq-accent));
   color: #FFFFFF;
   border-color: transparent;
   box-shadow: 0 1px 0 rgba(255,255,255,.35) inset, 0 2px 5px -1px rgba(194,74,11,.6);
}

/* Row-side mastery dot — passive signal of the effective grade. */
.iq-mastery-dot {
   width: 8px;
   height: 8px;
   border-radius: 999px;
   flex-shrink: 0;
   background: var(--iq-ink5);
}
.iq-mastery-dot.is-knew    { background: radial-gradient(circle at 35% 30%, #63C79A, var(--iq-greenDot) 70%); box-shadow: 0 0 5px rgba(46,158,107,.5); }
.iq-mastery-dot.is-shaky   { background: radial-gradient(circle at 35% 30%, #EDC55C, var(--iq-amberDot) 70%); box-shadow: 0 0 5px rgba(217,160,19,.5); }
.iq-mastery-dot.is-unknown { background: radial-gradient(circle at 35% 30%, #E07B62, var(--iq-roseDot) 70%); box-shadow: 0 0 5px rgba(196,68,46,.5); }
/* Mastered rows trade the dot for a small check — the one state worth
   scanning a list for gets a distinct mark. */
.iq-mastery-check { color: var(--iq-greenDot); flex-shrink: 0; }

/* margin-left:auto keeps the stat beside the result count on the right (the
   header is space-between; without it a third child floats to the center). */
.iq-section-mastered { color: var(--iq-green); margin-left: auto; margin-right: 12px; display: inline-flex; align-items: center; gap: 8px; }
/* Slim mastered-progress track (rides inside .iq-section-mastered; fill
   width is set inline by Alpine, same idiom as .iq-mic-level). */
.iq-progress {
   width: 72px;
   height: 4px;
   border-radius: 999px;
   background: var(--iq-rule);
   overflow: hidden;
   flex-shrink: 0;
}
.iq-progress > i { display: block; height: 100%; background: var(--iq-greenDot); border-radius: 999px; }

/* Expanded-row meta line ("BEGINNER · Knew it") — type from the shared mono
   label class; this only spaces it. */
.iq-row-meta {
   margin: 2px 0 12px;
   display: flex;
   align-items: center;
   gap: 6px 10px;
   flex-wrap: wrap;
}
/* In-row practice switch, right-aligned on the meta line. The graduation-cap
   icon matches the filter bar's Practice segment so the two read as the same
   control; sizing sits between the mono meta text and the footer action btn. */
.iq-row-practice {
   margin-left: auto;
   display: inline-flex;
   align-items: center;
   gap: 6px;
   padding: 4px 11px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 999px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 12.5px;
   font-weight: 600;
   letter-spacing: 0;
   text-transform: none;
   color: var(--iq-ink2);
   cursor: pointer;
   transition: border-color .15s ease, color .15s ease;
}
.iq-row-practice svg { color: var(--iq-accent); }
.iq-row-practice:hover { border-color: var(--iq-accent); color: var(--iq-accentD); }
.iq-row-practice:focus-visible { outline: 2px solid var(--iq-accent); outline-offset: 1px; }

/* Attempt panel — practice mode, pre-reveal. */
.iq-attempt {
   padding: 16px 18px;
   border-radius: 12px;
   background: var(--iq-card);
   border: 1px dashed var(--iq-rule);
}
.iq-attempt-hint { margin: 0 0 10px; font-size: 14px; color: var(--iq-ink3); }
.iq-attempt-input {
   display: block;
   width: 100%;
   resize: vertical;
   min-height: 84px;
   padding: 10px 12px;
   border-radius: 9px;
   border: 1px solid var(--iq-cardEdge);
   background: var(--iq-paper);
   font-family: 'Instrument Sans', sans-serif;
   font-size: 14.5px;
   color: var(--iq-ink);
   outline: none;
}
.iq-attempt-input:focus { border-color: var(--iq-accent); }
/* Dictation control — rendered only when the browser has SpeechRecognition.
   A LABELLED pill on its own row under the textarea, not a bare glyph in the
   input's corner: icon-only read as decoration, so nobody discovered that an
   answer can be spoken. The label also carries the state (Speak / Stop), which
   colour alone can't. Below the input it needs no right-padding gutter and
   never collides with the textarea's resize handle. */
.iq-attempt-inputwrap { position: relative; }
.iq-voice-row {
   display: flex;
   align-items: center;
   gap: 10px;
   flex-wrap: wrap;
   margin-top: 8px;
}
/* Containing block for the quality chooser, so it hangs off the button. */
.iq-voice-anchor { position: relative; }
.iq-mic-btn {
   display: inline-flex;
   align-items: center;
   gap: 7px;
   padding: 6px 13px 6px 11px;
   border: 1px solid var(--iq-cardEdge);
   border-radius: 999px;
   background: var(--iq-card);
   color: var(--iq-ink2);
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13px;
   font-weight: 600;
   cursor: pointer;
   transition: color .15s ease, background .15s ease, border-color .15s ease;
}
.iq-mic-btn svg { flex: 0 0 auto; }
.iq-mic-btn:hover { color: var(--iq-accentD); background: var(--iq-accentS); border-color: var(--iq-accentE); }
.iq-mic-btn.is-on {
   color: #F8F7F4;
   background: var(--iq-roseDot);
   border-color: var(--iq-roseDot);
   animation: iqMicPulse 1.6s ease-in-out infinite;
}
@keyframes iqMicPulse {
   0%, 100% { box-shadow: 0 0 0 0 rgba(194, 70, 50, .35); }
   50%      { box-shadow: 0 0 0 7px rgba(194, 70, 50, 0); }
}
@media (prefers-reduced-motion: reduce) {
   .iq-mic-btn.is-on { animation: none; }
}
.iq-mic-hint {
   display: flex;
   align-items: center;
   gap: 8px;
   margin: 6px 0 0;
   font-size: 13px;
   color: var(--iq-rose);
}
/* Live input level — flat while speaking means audio isn't reaching the
   browser (wrong OS input device), which is exactly what it's here to show. */
.iq-mic-level {
   flex-shrink: 0;
   width: 42px;
   height: 5px;
   border-radius: 999px;
   background: var(--iq-roseS);
   overflow: hidden;
}
.iq-mic-level i {
   display: block;
   height: 100%;
   width: 0;
   border-radius: 999px;
   background: var(--iq-roseDot);
   transition: width .08s linear;
}
/* Voice quality chooser — hangs off the Speak button (.iq-voice-anchor is its
   containing block). Opens on first mic click only when both the free browser
   path and premium STT exist; the picked mode is remembered per browser. */
.iq-stt-pop {
   position: absolute;
   top: calc(100% + 8px);
   left: 0;
   z-index: 30;
   width: min(300px, 78vw);
   padding: 10px;
   border: 1px solid var(--iq-cardEdge);
   border-radius: 11px;
   background: var(--iq-card);
   box-shadow: 0 10px 28px rgba(26, 22, 18, .14);
}
.iq-stt-pop-title {
   margin: 0 0 8px;
   font-size: 13px;
   font-weight: 600;
   color: var(--iq-ink3);
}
.iq-stt-opt {
   display: block;
   width: 100%;
   padding: 8px 9px;
   border: 1px solid var(--iq-cardEdge);
   border-radius: 9px;
   background: var(--iq-paper);
   text-align: left;
   cursor: pointer;
   transition: border-color .15s ease, background .15s ease;
}
.iq-stt-opt + .iq-stt-opt { margin-top: 6px; }
.iq-stt-opt:hover { border-color: var(--iq-accentE); background: var(--iq-accentS); }
.iq-stt-opt-name {
   display: flex;
   align-items: baseline;
   justify-content: space-between;
   gap: 8px;
   font-size: 14px;
   font-weight: 600;
   color: var(--iq-ink);
}
.iq-stt-opt-name em {
   font-style: normal;
   font-size: 12.5px;
   font-weight: 600;
   color: var(--iq-ink4);
   white-space: nowrap;
}
.iq-stt-opt.is-premium .iq-stt-opt-name em { color: var(--iq-accentD); }
.iq-stt-opt-desc {
   display: block;
   margin-top: 2px;
   font-size: 12.5px;
   line-height: 1.45;
   color: var(--iq-ink4);
}
/* Active-mode line under the textarea, with an inline switch back to the
   chooser. Hidden mid-session (recording/dictating/transcribing) — the mic
   hints own that space. */
.iq-stt-mode {
   margin: 6px 0 0;
   font-size: 12.5px;
   color: var(--iq-ink4);
}
.iq-stt-mode-switch {
   padding: 0;
   border: none;
   background: none;
   font-size: 12.5px;
   color: var(--iq-accentD);
   text-decoration: underline;
   cursor: pointer;
}
.iq-attempt-actions {
   display: flex;
   align-items: center;
   gap: 10px;
   flex-wrap: wrap;
   margin-top: 12px;
}
.iq-attempt-ai {
   background: transparent;
   color: var(--iq-accentD);
   border-color: var(--iq-accentE);
}
.iq-attempt-ai:hover:not(:disabled) { background: var(--iq-accentS); }
.iq-attempt-ai:disabled { opacity: .45; cursor: not-allowed; }
.iq-attempt-note { font-size: 13px; color: var(--iq-ink4); }
/* Footer line offering last session's paid grade back (explicit click). */
.iq-attempt-last {
   margin: 12px 0 0;
   font-size: 13px;
   color: var(--iq-ink4);
}
.iq-attempt-last-verdict { font-weight: 600; }
.iq-attempt-last-verdict.is-knew    { color: var(--iq-green); }
.iq-attempt-last-verdict.is-shaky   { color: var(--iq-amber); }
.iq-attempt-last-verdict.is-unknown { color: var(--iq-rose); }
.iq-attempt-last-view {
   appearance: none;
   border: none;
   background: transparent;
   cursor: pointer;
   padding: 0;
   margin-left: 6px;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13px;
   font-weight: 600;
   color: var(--iq-accentD);
}
.iq-attempt-last-view:hover:not(:disabled) { text-decoration: underline; }
.iq-attempt-last-view:disabled { opacity: .6; cursor: default; }
.iq-grade-error { margin: 10px 0 0; font-size: 13.5px; color: var(--iq-rose); }
.iq-grade-error a { color: var(--iq-accentD); font-weight: 600; text-decoration: none; margin-left: 6px; }
.iq-grade-error a:hover { text-decoration: underline; }

/* "Your answer" card — the typed attempt, frozen read-only above the revealed
   canonical answer. Same dashed treatment as the attempt panel so it reads as
   the same artifact in a new state. */
.iq-your-answer {
   margin-bottom: 14px;
   padding: 12px 16px;
   border-radius: 12px;
   background: var(--iq-card);
   border: 1px dashed var(--iq-rule);
}
.iq-your-answer-head {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 10px;
   margin-bottom: 6px;
}
.iq-your-answer-label {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   font-weight: 400;
   text-transform: uppercase;
   letter-spacing: .06em;
   color: var(--iq-ink4);
}
.iq-your-answer-actions { display: inline-flex; align-items: center; gap: 10px; }
.iq-your-answer-grade { padding: 5px 12px; font-size: 13px; }
.iq-your-answer-retry {
   appearance: none;
   border: none;
   background: transparent;
   cursor: pointer;
   padding: 0;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13px;
   font-weight: 600;
   color: var(--iq-ink4);
}
.iq-your-answer-retry:hover { color: var(--iq-ink2); text-decoration: underline; }
.iq-your-answer-text {
   margin: 0;
   font-size: 14.5px;
   line-height: 1.55;
   color: var(--iq-ink2);
   white-space: pre-wrap;      /* typed answers keep their line breaks */
   overflow-wrap: break-word;
}

/* Self-grade bar — below the revealed answer (practice mode only). */
.iq-grade {
   margin-top: 14px;
   padding-top: 14px;
   border-top: 1px solid var(--iq-rule);
}
.iq-grade-row {
   display: flex;
   align-items: center;
   gap: 12px;
   flex-wrap: wrap;
}
.iq-grade-label { font-size: 14px; font-weight: 600; color: var(--iq-ink2); }
.iq-grade-btns { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.iq-grade-btn {
   appearance: none;
   cursor: pointer;
   padding: 6px 12px;
   border-radius: 999px;
   border: 1px solid var(--iq-cardEdge);
   background: var(--iq-card);
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13.5px;
   font-weight: 600;
   color: var(--iq-ink3);
   transition: all .15s ease;
}
.iq-grade-btn:hover { border-color: var(--iq-ink4); }
.iq-grade-knew.is-on    { background: var(--iq-greenS); color: var(--iq-green); border-color: var(--iq-greenDot); }
.iq-grade-shaky.is-on   { background: var(--iq-amberS); color: var(--iq-amber); border-color: var(--iq-amberDot); }
.iq-grade-unknown.is-on { background: var(--iq-roseS);  color: var(--iq-rose);  border-color: var(--iq-roseDot); }

/* AI verdict pill + structured feedback (x-text only — never HTML). */
.iq-grade-ai-pill {
   display: inline-flex;
   align-items: center;
   gap: 4px;
   padding: 4px 10px;
   border-radius: 999px;
   font-size: 13px;
   font-weight: 600;
   background: var(--iq-paper);
   border: 1px solid var(--iq-cardEdge);
   color: var(--iq-ink3);
}
.iq-grade-ai-pill.is-knew    { background: var(--iq-greenS); color: var(--iq-green); border-color: var(--iq-greenDot); }
.iq-grade-ai-pill.is-shaky   { background: var(--iq-amberS); color: var(--iq-amber); border-color: var(--iq-amberDot); }
.iq-grade-ai-pill.is-unknown { background: var(--iq-roseS);  color: var(--iq-rose);  border-color: var(--iq-roseDot); }
.iq-grade-feedback {
   margin-top: 12px;
   padding: 12px 14px;
   border-radius: 10px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
}
.iq-grade-summary { margin: 0 0 8px; font-size: 14px; font-weight: 600; color: var(--iq-ink); }
.iq-grade-points { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.iq-grade-points li { font-size: 13.5px; color: var(--iq-ink2); display: flex; gap: 8px; align-items: baseline; }
.iq-grade-point-tag {
   flex-shrink: 0;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11px;
   font-weight: 400;
   text-transform: uppercase;
   letter-spacing: .04em;
   padding: 1px 6px;
   border-radius: 5px;
}
.iq-grade-points li.is-good    .iq-grade-point-tag { background: var(--iq-greenS); color: var(--iq-green); }
.iq-grade-points li.is-missing .iq-grade-point-tag { background: var(--iq-amberS); color: var(--iq-amber); }
.iq-grade-points li.is-wrong   .iq-grade-point-tag { background: var(--iq-roseS);  color: var(--iq-rose); }

@media (max-width: 879px) {
   .iq-grade-row { align-items: flex-start; }
   .iq-attempt-actions .iq-btn { flex: 1; justify-content: center; }
   .iq-mode { width: 100%; }
   .iq-mode-btn { flex: 1; justify-content: center; }
}

/* ---- Mock interview CTA (subject hub) --------------------------------- */
.iq-mi-cta {
   margin: 22px 0 0;
   padding: 16px 18px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-left: 4px solid var(--iq-subject, var(--iq-accent));
   border-radius: 12px;
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 14px;
   flex-wrap: wrap;
}
.iq-mi-cta p { margin: 0; color: var(--iq-ink2); font-size: 0.92rem; }
.iq-mi-cta p strong { color: var(--iq-ink); }
.iq-mi-cta a {
   flex-shrink: 0;
   display: inline-flex;
   align-items: center;
   gap: 7px;
   padding: 9px 16px;
   border-radius: 999px;
   background: var(--iq-accent);
   color: #F8F7F4;
   font-weight: 600;
   font-size: 0.9rem;
   text-decoration: none;
}
.iq-mi-cta a:hover { background: var(--iq-accentD); }

/* ---- Round bridge (subject hub) ---------------------------------------
   Same card chrome as the mock-interview CTA above, but OUTLINE pills rather
   than one filled accent button: the filled pill is that CTA's identity, and
   two of them stacked would compete for the same "do this next". */
.iq-round-cta {
   margin: 22px 0 0;
   padding: 16px 18px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-left: 4px solid var(--iq-subject, var(--iq-accent));
   border-radius: 12px;
}
.iq-round-cta p { margin: 0 0 12px; color: var(--iq-ink2); font-size: 0.92rem; }
.iq-round-cta p strong { color: var(--iq-ink); }
.iq-round-cta-list { display: flex; flex-wrap: wrap; gap: 8px; }
.iq-round-cta-list a {
   display: inline-flex;
   flex-direction: column;
   gap: 2px;
   padding: 8px 14px;
   border-radius: 10px;
   border: 1px solid var(--iq-cardEdge);
   background: var(--iq-paper, transparent);
   text-decoration: none;
   transition: border-color .15s ease, background-color .15s ease;
}
.iq-round-cta-list a:hover {
   border-color: var(--iq-subject, var(--iq-accent));
   background: var(--iq-card);
}
.iq-round-cta-list .kk {
   font-size: 0.68rem;
   font-weight: 600;
   letter-spacing: 0.06em;
   text-transform: uppercase;
   color: var(--iq-ink3);
}
.iq-round-cta-list .tt { font-size: 0.9rem; font-weight: 600; color: var(--iq-ink); }

/* ---- Related topics (subject hub) -------------------------------------
   The lateral move along the TECHNOLOGY axis, sitting above the round bridge.
   Deliberately the QUIETEST of the three closing blocks: this one continues
   what the user is already doing, the round bridge switches axis, and the
   mock-interview CTA is the terminal ask. So no left accent bar (that is the
   round bridge's mark) and no fill (that is the CTA's) - just card chrome. */
.iq-related {
   margin: 22px 0 0;
   padding: 16px 18px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 12px;
}
.iq-related p { margin: 0 0 12px; color: var(--iq-ink2); font-size: 0.92rem; }
.iq-related p strong { color: var(--iq-ink); }
.iq-related-group + .iq-related-group { margin-top: 12px; }
.iq-related-label {
   display: block;
   margin-bottom: 7px;
   font-size: 0.68rem;
   font-weight: 600;
   letter-spacing: 0.06em;
   text-transform: uppercase;
   color: var(--iq-ink3);
}
.iq-related-list { display: flex; flex-wrap: wrap; gap: 8px; }
.iq-related-list a {
   display: inline-flex;
   flex-direction: column;
   gap: 2px;
   padding: 8px 14px;
   border-radius: 10px;
   border: 1px solid var(--iq-cardEdge);
   background: var(--iq-paper, transparent);
   text-decoration: none;
   transition: border-color .15s ease, background-color .15s ease;
}
.iq-related-list a:hover {
   border-color: var(--iq-subject, var(--iq-accent));
   background: var(--iq-card);
}
.iq-related-list .tt { font-size: 0.9rem; font-weight: 600; color: var(--iq-ink); }
.iq-related-list .kk { font-size: 0.72rem; color: var(--iq-ink3); }

/* ============================================================
   Single-question page: Interview lens + practice + discovery
   ============================================================ */

/* --- Interview lens card --- */
.iq-lens-zone { margin: 26px 0 0; }
.iq-lens {
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 14px;
   padding: 20px 22px;
}
.iq-lens-head {
   display: flex;
   align-items: baseline;
   justify-content: space-between;
   gap: 12px;
   flex-wrap: wrap;
   margin-bottom: 14px;
}
.iq-lens-sub { font-size: 13.5px; color: var(--iq-ink4); }
.iq-lens-grid {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 18px 26px;
}
.iq-lens-followups { grid-column: 1 / -1; }
.iq-lens-h {
   margin: 0 0 8px;
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 11.5px;
   font-weight: 400;
   letter-spacing: 0.1em;
   text-transform: uppercase;
   color: var(--iq-ink3);
}
.iq-lens-list { list-style: none; margin: 0; padding: 0; }
.iq-lens-item { padding: 7px 0; }
.iq-lens-item + .iq-lens-item { border-top: 1px solid var(--iq-divider); }
.iq-lens-q { display: block; font-weight: 600; font-size: 0.95rem; color: var(--iq-ink); }
.iq-lens-q-link { text-decoration: none; }
.iq-lens-q-link:hover { color: var(--iq-accentD); text-decoration: underline; }
.iq-lens-hint { display: block; margin-top: 2px; font-size: 0.86rem; color: var(--iq-ink3); }
/* list-style restated: the global reset strips ol markers, but the beats are
   a speaking ORDER — the numbers are content here. */
.iq-lens-beats { margin: 0; padding: 0 0 0 22px; list-style: decimal outside; }
.iq-lens-beat { padding: 4px 0; font-size: 0.92rem; color: var(--iq-ink2); }
.iq-lens-beat::marker {
   font-family: 'Fragment Mono', ui-monospace, monospace;
   font-size: 12px;
   font-weight: 400;
   color: var(--iq-accent);
}
.iq-lens-mistake { border-left: 2px solid var(--iq-roseDot); padding-left: 10px; }
.iq-lens-mistake + .iq-lens-mistake { border-top: none; margin-top: 8px; }
.iq-lens-mistake-label { display: block; font-weight: 600; font-size: 0.92rem; color: var(--iq-ink); }
.iq-lens-mistake-why { display: block; margin-top: 2px; font-size: 0.86rem; color: var(--iq-ink3); }

/* --- Lens open CTA + fresh take --- */
/* Compact single-row tool: mono label + copy left, ghost button right.
   Solid edge on purpose — dashed reads as "placeholder for generated
   stuff"; the lens should feel like curated content behind a door. */
.iq-lens-cta {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 16px;
   flex-wrap: wrap;
   padding: 14px 20px;
   border-radius: 14px;
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
}
.iq-lens-cta-lead { flex: 1 1 320px; min-width: 0; }
.iq-lens-cta-copy { margin: 5px 0 0; font-size: 0.92rem; color: var(--iq-ink3); max-width: 60ch; }
.iq-lens-cta-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.iq-lens-cta-note { font-family: 'Instrument Sans', sans-serif; font-size: 12.5px; color: var(--iq-ink4); }
.iq-lens-regen { display: flex; justify-content: flex-end; margin-top: 8px; }
.iq-lens-regen-btn {
   appearance: none;
   cursor: pointer;
   padding: 5px 12px;
   border-radius: 999px;
   border: 1px solid var(--iq-cardEdge);
   background: var(--iq-card);
   font-family: 'Instrument Sans', sans-serif;
   font-size: 13px;
   font-weight: 600;
   color: var(--iq-ink3);
   transition: all .15s ease;
}
.iq-lens-regen-btn:hover { border-color: var(--iq-ink4); color: var(--iq-ink); }
.iq-lens-regen-btn:disabled { opacity: 0.6; cursor: default; }
.iq-lens-error { margin: 8px 0 0; font-size: 0.86rem; color: var(--iq-rose); }
.iq-lens-error-link { color: var(--iq-accentD); font-weight: 600; text-decoration: underline; margin-left: 4px; }

/* --- "Learn the concept" pointer --- */
.iq-concept { margin: 18px 2px 0; }
.iq-concept-line { margin: 4px 0; font-size: 0.92rem; color: var(--iq-ink3); }
.iq-concept-link { color: var(--iq-accentD); font-weight: 600; text-decoration: none; }
.iq-concept-link:hover { text-decoration: underline; }

/* --- Post-answer practice strip (grade bar + compare-your-answer fold) --- */
.iq-single-practice {
   background: var(--iq-card);
   border: 1px solid var(--iq-cardEdge);
   border-radius: 14px;
   padding: 16px 22px;
   /* The visual section now sits between the answer card and this strip
      (when a figure serves) — a plain gap reads right in both layouts,
      so no negative tuck against whatever precedes it. */
   margin: 18px 0 24px;
}
/* Locked pages keep the wrapper (its init registers keyboard nav) but render
   no controls — strip the card chrome so nothing empty is drawn. */
.iq-single-practice-bare { background: none; border: none; padding: 0; margin: 0; }
/* The grade bar's "Try again" escape hatch collapses a hub row back to
   attempt-first; the single page has no attempt-first state, so for a visitor
   with no typed text it would be a button that visibly does nothing — hide it
   here only. (The attempt fold's own Clear button lives outside .iq-grade and
   is unaffected; "View answer & feedback" stays, it works everywhere.) */
.iq-single-practice .iq-grade .iq-your-answer-retry { display: none; }
.iq-single-practice .iq-grade { margin-top: 0; padding-top: 0; border-top: none; }
.iq-grade-anon-note { margin: 8px 0 0; font-size: 0.82rem; color: var(--iq-ink4); }
.iq-grade-anon-note a { color: var(--iq-accentD); font-weight: 600; text-decoration: none; }
.iq-grade-anon-note a:hover { text-decoration: underline; }
.iq-attempt-fold { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--iq-rule); }
.iq-attempt-fold-toggle {
   appearance: none;
   border: none;
   background: none;
   padding: 0;
   cursor: pointer;
   font-family: 'Instrument Sans', sans-serif;
   font-size: 14px;
   font-weight: 600;
   color: var(--iq-ink3);
   text-align: left;
}
.iq-attempt-fold-toggle:hover { color: var(--iq-ink); }
.iq-attempt-fold-toggle::before { content: '▸ '; color: var(--iq-accent); }
.iq-attempt-fold-toggle[aria-expanded="true"]::before { content: '▾ '; }
.iq-attempt-compact { margin-top: 12px; }
.iq-attempt-note { font-size: 0.82rem; color: var(--iq-ink4); }

/* --- Quiet daily-email nudge + position count --- */
.iq-daily-nudge { margin: 14px 0 0; text-align: center; font-size: 0.88rem; color: var(--iq-ink4); }
.iq-daily-nudge a { color: var(--iq-accentD); font-weight: 600; text-decoration: none; }
.iq-daily-nudge a:hover { text-decoration: underline; }
.iq-detail-count { color: var(--iq-ink5); font-weight: 700; }

@media (max-width: 880px) {
   .iq-lens { padding: 16px 16px; }
   .iq-lens-grid { grid-template-columns: 1fr; gap: 16px; }
   .iq-single-practice { padding: 14px 16px; }
}
