/* ---- A1. Missing tokens -----------------------------------------------
   Three variables were referenced with a fallback but never declared, so
   the fallback was silently doing the work:
     --r-md     browse filter panel + search drop radius
     --cta-bg   the header CTA's resting tint
     --ok / --danger  form success/error had three hard-coded greens and
                three hard-coded reds with no dark-mode counterpart at all.
   Light values match what is painted today, so this changes nothing
   visually; the dark block below is what actually fixes the bug. */
:root{
  --r-md:12px;
  --cta-bg:var(--header-hover);
  --ok:#067A52;        --ok-bg:#E7F6EF;        --ok-line:#A7DFC6;
  --danger:#A11B1B;    --danger-bg:#FEF2F2;    --danger-line:#FECACA;
}
/* Form messages, verified/warn tags, the "coming soon" chip and the deal
   border were all light-only literals: in dark mode the text switched to
   the dark palette while the background stayed near-white, which is how a
   success message ends up dark-green-on-white inside a near-black page.
   --ok / --danger deliberately sit at the same saturation as the existing
   --free / --deal families so a success message and a "Free" badge read
   as one palette rather than two. */
:root[data-theme="dark"]{
  --ok:#4ADE80;              --ok-bg:rgba(74,222,128,.13);   --ok-line:rgba(74,222,128,.34);
  --danger:#FF9A9A;          --danger-bg:rgba(255,154,154,.13); --danger-line:rgba(255,154,154,.34);
}

/* ---- A2. Elementor kit font globals had no fallback stack -------------
   These four re-declare the Elementor presets with BARE family names, so
   any widget using a kit preset has no fallback at all and drops to the
   browser default if the webfont is slow or blocked — the exact failure
   the token file warns about further up. Point them at the tokens, which
   carry a real fallback chain, keeping the preset names Elementor expects
   so the admin UI still reads Inter / Space Grotesk. */
body[class]{
  --e-global-typography-primary-font-family:'Space Grotesk','Inter',-apple-system,BlinkMacSystemFont,sans-serif;
  --e-global-typography-secondary-font-family:'Space Grotesk','Inter',-apple-system,BlinkMacSystemFont,sans-serif;
  --e-global-typography-text-font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --e-global-typography-accent-font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
}

/* ---- A3. One container width + one gutter -----------------------------
   Two separate alignment defects, both caused by the chrome ignoring the
   same two variables the sections obey.

   Width: --max (1440px) governs every section, but the header and footer
   were separately pinned to 1280px. Above ~1720px the header edge and the
   content edge sat 70px apart on each side, so the page visibly jogs at the
   fold between header and first section.

   Gutter: the chrome used a hard-coded 16px horizontal padding while the
   sections use --gutter, which steps 16 → 20 → 28 → 32. Measured on the
   live site, the header's content edge sat 16px left of the content grid
   at 1440 and 4px left at 768 — the header text and the page text below it
   were never on the same vertical line.

   NOTE the `body ` prefix. The original rules are written as
   `body .tdt-header-inner{...}` (specificity 0,1,1); a bare `.tdt-header-
   inner` is 0,1,0 and loses, which is why an earlier attempt at this fix
   changed nothing. The prefix is load-bearing, not decoration. */
body .tdt-header-inner,
body .tdt-footer-inner,
body .tdt-footer-bottom{ max-width:var(--max); }
body .tdt-header-inner,
body .tdt-footer-inner,
body .tdt-footer-bottom{
  padding-left:var(--gutter);
  padding-right:var(--gutter);
}
/* The sponsor banner carried a hard-coded 48px inner padding that matched
   no gutter value; it now tracks the same responsive gutter. */
.tdt-strip .tdt-banner{
  max-width:var(--max);
  padding-left:var(--gutter);
  padding-right:var(--gutter);
}

/* ---- A4. Dark mode: card borders that could not re-theme --------------
   Two card variants hover to a literal #D4D4D8. Every other card uses
   var(--line-hover), a near-transparent white in dark mode — so these two
   alone painted a LIGHT GREY border around a near-black card on hover.
   Same intent, token this time. */
.tdt-card--ref:hover,
.wp-block-post-template>li.wp-block-post:hover{ border-color:var(--line-hover); }

/* ---- A5. Dark mode: shadows and glows that stayed light ---------------
   Shadows were written as rgba(23,23,23,a) — the LIGHT --ink. --ink flips
   to #E9ECF4 in dark but a literal does not, so the search panel and the
   results dropdown cast a near-black shadow onto a near-black surface and
   lost all their depth. --shadow/--shadow-lg already swap per theme, so
   use them instead of re-spelling the value. */
.tdt-search-panel,
.tdt-search-drop{ box-shadow:var(--shadow-lg); }
/* Same class of bug for the accent glow: rgba(36,84,255,a) is the LIGHT
   --accent, so a light-blue button in dark mode sat inside a dark-blue
   halo. --accent-glow tracks the theme. */
:root{
  --accent-glow:rgba(36,84,255,.18);
  --accent-glow-lg:rgba(36,84,255,.28);
}
:root[data-theme="dark"]{
  --accent-glow:rgba(125,155,255,.20);
  --accent-glow-lg:rgba(125,155,255,.30);
}
.tdt-newsletter--v4signal .tdt-newsletter__form button:hover,
.tdt-newsletter--v4bottom .tdt-newsletter__form button:hover{ box-shadow:0 6px 18px var(--accent-glow); }

/* ---- A6. Trust + status tags that never re-themed ---------------------
   .tdt-tag--verified and .tdt-tag--warn were written with light-theme
   literals and have no dark counterpart, so they stayed dark-on-pale while
   the rest of the card went dark. Now tokenised. */
.tdt-tag--verified{
  color:var(--ok);
  background:var(--ok-bg);
  border-color:var(--ok-line);
}
.tdt-tag--warn{
  color:var(--deal);
  background:var(--deal-bg);
}
.tdt-form-msg--ok{
  background:var(--ok-bg);
  border-color:var(--ok-line);
  color:var(--ok);
}
.tdt-form-msg--err{
  background:var(--danger-bg);
  border-color:var(--danger-line);
  color:var(--danger);
}
/* The green "verified" dot and the green banner dot were the same colour
   spelled twice, neither of them a token. */
.tdt-card__dot,
.tdt-banner__dot{ background:var(--ok); }
.tdt-banner__dot{ box-shadow:0 0 0 3px var(--ok-bg); }
/* .tdt-deal carried a light-only warm tint border. */
.tdt-deal{ border-color:var(--deal-bg); }

/* ---- A7. Theme toggle ran its own blue palette ------------------------
   The most persistent control on the site shipped four hand-picked blues
   (#6D8CFF / #2454FF / #4C6EF5 / #A8BCFF) that are neither the brand blue
   nor the accent token. Re-pointed at the accent, which already flips for
   the theme, so the toggle can no longer disagree with it. Icon ink
   follows --accent-ink: the token file's own note warns that white-on-
   accent drops from 5.55:1 to 2.62:1 in dark. */
.tdt-theme{ background:var(--accent); }
.tdt-theme:hover{ background:var(--accent); filter:brightness(1.08); }
:root[data-theme="dark"] .tdt-theme,
:root[data-theme="dark"] .tdt-theme:hover{ background:var(--accent); filter:none; }
.tdt-theme svg{ color:var(--accent-ink); }

/* ---- A8. Newsletter submit button had lost its hover state -------------
   A later `!important` pins this button's resting colour, which silently
   removed the hover rule that came before it. Restore the affordance.
   (The button's SHAPE is deliberately left alone: the header's primary CTA
   is a rounded rectangle rather than a pill, which is a brand question, not
   a defect. It is listed in the owner-decision list rather than "fixed"
   here — an earlier version of this block forced 999px and it was a no-op
   anyway, losing to the attribute selector already on the rule.) */
.tdt-newsletter__form button:hover{ background:var(--accent); }

/* ---- A9. Card descriptions truncate the same way everywhere -----------
   Three mechanisms were in play: -webkit-line-clamp:3 in the design
   system, -webkit-line-clamp:2 in the polish layer, and on the browse grid
   a bare max-height:4.5em with overflow:hidden — which clips mid-glyph
   with NO ellipsis and, because it also forced min-height:0, destroyed
   the reserved box that keeps every card foot on a shared baseline within
   a row. One clamp, one reserved height, and the browse grid joins the
   others instead of overriding them. */
.tdt-card__desc{
  display:-webkit-box;
  -webkit-box-orient:vertical;
  -webkit-line-clamp:3;
  line-clamp:3;
  overflow:hidden;
  min-height:calc(3 * 1.5em);
}
.tdt-browse--v2 .tdt-card__desc{
  display:-webkit-box;
  -webkit-box-orient:vertical;
  -webkit-line-clamp:3;
  line-clamp:3;
  max-height:none;
  overflow:hidden;
  /* !important is unavoidable here. The pre-existing browse rule is
     `.tdt-browse--v2 .tdt-card__desc{...min-height:0!important}`, the same
     specificity as this one, and `!important` always outranks a normal
     declaration regardless of specificity — so the only way to restore the
     reserved box is to match it. Without this the clamp above applies but
     the reserved height does not, and card feet stop sharing a baseline
     within a row. Measured live at 360/390/768px before this fix:
     min-height resolved to 0px. */
  min-height:calc(3 * 1.5em) !important;
}
.tdt-browse--v2 .tdt-card__why{
  display:-webkit-box;
  -webkit-box-orient:vertical;
  -webkit-line-clamp:1;
  line-clamp:1;
  overflow:hidden;
  min-height:1.5em;
}

/* ---- A10. Grid rhythm -------------------------------------------------
   .tdt-grid gap was written five times across the file (12/14/16/18px)
   and the coherence patch was holding it in place with !important. Same
   fix, stated once, from the spacing scale. */
.tdt-grid{ gap:var(--s-4); }
.tdt-disc-grid{ gap:var(--s-4); }