/* ============================================================================
   SWiP UI — the design system's single stylesheet
   Version 3.2 · 31.07.2026
   ----------------------------------------------------------------------------
   The single source of components for the SWiP site. A page links this file and
   adds only its own page-specific CSS. A component living inside one page's
   <style> block is a breach of the standard.

   No frameworks, no preprocessors, no external dependencies.
   Fonts are self-hosted (see the @font-face block below).

   Contents
   01. Tokens: primitive
   02. Tokens: semantic
   03. Tokens: theme (overridden per vertical)
   04. Spacing, radii, shadows, motion, layers, icons
   05. Reset and base
   06. Layout: containers, sections, grid
   07. Typography
   08. Section header and section note
   09. Buttons
   10. Cards
   11. Tags and badges
   12. Metrics (money figures)
   13. Forms
   14. Accordion
   15. Tabs
   16. Dialog
   17. Table
   18. Tooltip and dropdown
   19. Utilities
   ============================================================================ */


/* ── 01. Tokens: primitive ───────────────────────────────────────────────────
   The palette. NOT used directly in components — only through semantic. */
:root {
  --n1:#141416; --n2:#23262F; --n3:#353945; --n4:#777E90; --n5:#B1B5C3;
  --n6:#E6E8EC; --n7:#F4F5F6; --n8:#FCFCFD; --n9:#FFFFFF;
  --quiet:#5F6875;   /* v3.3.3: was #6B7280 — 4.83 on white, but 4.43 on --bg-subtle,
                        4.46 on --money-soft and 3.94 on --bg-sunken: failed the 4.5 minimum.
                        Now 5.64 / 5.17 / 5.20 / 4.60 — passes on all four */

  /* Two greens. Pick by background, not by taste */
  --green-bright:#26C878;  --green-bright-hover:#3DD98A;  /* DARK background */
  --green-light:#00B868;   --green-light-hover:#00A65D;   /* LIGHT background */
  --green-soft:#E8FAF1;

  --red:#FF3838; --red-dark:#C41F1F;
  --amber:#FFA53B;
  --blue:#5672D4; --brand-green-dark:#048550;
  --orange:#FF7A33; --orange-deep:#FE5000;
}


/* ── 02. Tokens: semantic ────────────────────────────────────────────────────
   The role in the interface. This is what components use. */
:root {
  --text:          var(--n1);
  --text-2:        var(--n3);
  --text-muted:    var(--quiet);   /* quiet text, .section-note, placeholder */
  --text-on-fill:  var(--n9);      /* WHITE: labels on colored fills, §1.1a */
  --text-inverse:  var(--n9);

  --bg:            var(--n9);
  --bg-2:          var(--n8);
  --bg-subtle:     var(--n7);
  --bg-sunken:     var(--n6);

  --border:        var(--n6);      /* dividers, outline buttons, outline tags */
  --border-control:var(--n4);      /* input borders, 4.06:1 */

  --money-on-dark: var(--green-bright); /* #26C878 — dark sections */
  --money-fill:    var(--green-light);  /* #00B868 — fill on light */
  --money-text:    var(--green-light);  /* #00B868 — green TEXT on light */
  --money-soft:    var(--green-soft);

  --danger:        var(--red);          /* fill with white text */
  --danger-text:   var(--red-dark);     /* error text on light, 5.89:1 */
  --danger-on-dark:var(--red);          /* red text in a dark section, 5.15:1 */
  --campaign:      var(--amber);
}


/* ── 03. Tokens: theme ───────────────────────────────────────────────────────
   Overridden per vertical. Nothing else is. */
:root {
  --cta:               var(--money-fill);
  --cta-hover:         var(--green-light-hover);
  --cta-on-dark:       var(--money-on-dark);
  --cta-on-dark-hover: var(--green-bright-hover);
  --cta-text:          var(--text-on-fill);
  --accent-bg:         transparent;
  --ring:              color-mix(in srgb, var(--cta) 45%, transparent);
}

/* Sit-down café. Other verticals are added as identical blocks */
.theme-cafe {
  --cta:               #B08D4F;
  --cta-hover:         #8F7140;
  --cta-on-dark:       #D4B478;
  --cta-on-dark-hover: #E0C69A;
  --accent-bg:         #F7F1E6;
}


/* ── 04. Spacing, radii, shadows, motion, layers, icons ─────────────────── */
:root {
  /* A 4/8 scale. No value outside the scale may appear in the code */
  --sp-1:4px;  --sp-2:8px;  --sp-3:12px; --sp-4:16px; --sp-5:20px;
  --sp-6:24px; --sp-8:32px; --sp-10:40px; --sp-12:48px; --sp-16:64px;
  --sp-18:72px; --sp-25:100px;

  /* Radii are set by the designer. Hardcoding them in components is forbidden */
  --radius-card:24px; --radius-inner:16px;
  --radius-btn:10px;  --radius-btn-sm:6px; --radius-tag:8px;

  /* Exactly two shadows. Cards carry none */
  --shadow-lg:0 20px 40px rgba(0,0,0,.1);  /* dropdowns, menus, overlays */
  --shadow-sm:0 10px 30px rgba(0,0,0,.1);  /* floating controls, tooltips */

  --dur-fast:120ms; --dur:200ms; --dur-slow:320ms;
  --ease:cubic-bezier(.2,.8,.2,1);

  --z-header:100; --z-dropdown:200; --z-overlay:300;
  --z-dialog:310; --z-tooltip:400; --z-toast:500;

  --icon-lg:20px; --icon-sm:16px;

  /* Containers */
  --container-content:1120px;
  --container-wide:1280px;
  --container-hero:1440px;

  --font-base:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --font-note:'Nunito Sans',-apple-system,BlinkMacSystemFont,sans-serif;
}

@media (max-width:768px) {
  :root { --radius-card:16px; --radius-inner:12px; }
}

/* Fonts — self-hosted Inter, latin subset. Paths are relative to THIS file
   (assets/css/), so they climb one level to assets/fonts/. Relative on purpose:
   the package then works from a subdirectory too, which absolute /assets/ paths
   would break on a staging mount. */
@font-face{font-family:'Inter';src:url('../fonts/Inter-Regular.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Inter';src:url('../fonts/Inter-SemiBold.woff2') format('woff2');
  font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:'Inter';src:url('../fonts/Inter-Bold.woff2') format('woff2');
  font-weight:700;font-style:normal;font-display:swap}


/* ── 05. Reset and base ─────────────────────────────────────────────────── */
*,*::before,*::after { box-sizing:border-box; }

html { -webkit-text-size-adjust:100%; scroll-behavior:smooth; }

body {
  margin:0;
  font-family:var(--font-base);
  font-size:16px; line-height:1.55;
  color:var(--text); background:var(--bg);
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
}

img,video,svg { max-width:100%; height:auto; display:block; }

button,input,textarea,select { font-family:inherit; font-size:inherit; }

/* Focus. :focus-visible, not :focus. outline:none with no replacement is forbidden */
:focus-visible { outline:3px solid var(--ring); outline-offset:2px; border-radius:2px; }

/* Skip link — the first focusable element on the page */
.skip-link {
  position:absolute; inset-inline-start:var(--sp-4); inset-block-start:-100px;
  z-index:calc(var(--z-header) + 1);
  padding:var(--sp-3) var(--sp-4); border-radius:var(--radius-btn);
  background:var(--text); color:var(--text-inverse);
  font-weight:700; text-decoration:none;
  transition:inset-block-start var(--dur-fast) var(--ease);
}
.skip-link:focus { inset-block-start:var(--sp-4); }

@media (prefers-reduced-motion:reduce) {
  *,*::before,*::after {
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important;
  }
}


/* ── 06. Layout ─────────────────────────────────────────────────────────── */
.container      { max-width:var(--container-content); margin-inline:auto; padding-inline:var(--sp-6); }
.container-wide { max-width:var(--container-wide);    margin-inline:auto; padding-inline:var(--sp-6); }
.hero-inner     { max-width:var(--container-hero);    margin-inline:auto; padding-inline:var(--sp-6); }

section              { padding-block:var(--sp-25); }
section.is-compact   { padding-block:var(--sp-18); }
@media (max-width:768px) { section, section.is-compact { padding-block:var(--sp-16); } }

/* Dark section. Inside it, components switch to their dark variants on their own */
.section--dark { background:var(--n1); color:var(--text-inverse); }
.section--dark .lede,
.section--dark .section-note { color:var(--n5); }
.section--subtle { background:var(--bg-subtle); }
.section--accent { background:var(--accent-bg); }

/* Grid: 12 columns, 32px gutter */
.grid    { display:grid; gap:var(--sp-8); grid-template-columns:repeat(12,1fr); }
.grid-2  { display:grid; gap:var(--sp-8); grid-template-columns:repeat(auto-fit,minmax(320px,1fr)); }
.grid-3  { display:grid; gap:var(--sp-8); grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); }
.grid-4  { display:grid; gap:var(--sp-6); grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); }


/* ── 07. Typography ─────────────────────────────────────────────────────── */
h1,h2,h3,h4 { margin:0 0 var(--sp-4); font-family:var(--font-base); }

/* Headings and subheadings use text-wrap:balance.
   Exception: the hero H1 with manual line breaks, see .hero-title below */
h1,h2,h3,h4,.h1,.h2,.h3,.h4,
.lede,.card__title,.dialog__title,.section-header .lede,
.accordion__item > summary { text-wrap:balance; }

h1, .h1 {
  font-size:clamp(52px,5vw,72px); line-height:1.02;
  letter-spacing:-.02em; font-weight:700;
}
/* Hero H1 — line breaks controlled with <br>, not browser wrapping */
.hero-title { max-width:980px; text-wrap:normal !important; white-space:normal; }
.hero-title span { display:inline-block; }

h2, .h2 {
  font-size:clamp(38px,3.2vw,48px); line-height:1.08;
  letter-spacing:-.02em; font-weight:700;
}
h3, .h3 { font-size:clamp(24px,2vw,28px); line-height:1.2; font-weight:700; }
h4, .h4 { font-size:20px; line-height:1.3; font-weight:600; }

.lede    { font-size:20px; line-height:1.5; font-weight:400; color:var(--text-2); max-width:65ch; }
p        { margin:0 0 var(--sp-4); max-width:75ch; }
.small   { font-size:14px; line-height:1.45; color:var(--text-muted); }
.caption { font-size:12px; line-height:1.4; font-weight:600; }
.eyebrow {
  font-size:12px; font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--text-muted); margin:0 0 var(--sp-3);
}
@media (max-width:768px) { .lede { font-size:18px; } }

a { color:var(--money-text); text-decoration:underline; text-underline-offset:2px; }
a:hover { text-decoration-thickness:2px; }
.section--dark a { color:var(--money-on-dark); }


/* ── 08. Section header and section note ────────────────────────────────── */
.section-header {
  max-width:1040px; margin:0 auto var(--sp-12);
  text-align:center; padding-inline:var(--sp-6);
}
.section-header h2   { max-width:1040px; margin-inline:auto; }
.section-header .lede{ max-width:860px; margin:18px auto 0; }
.section-header.is-wide      { max-width:var(--container-content); }
.section-header.is-wide h2   { max-width:var(--container-content); }
.section-header.is-compact   { margin-bottom:36px; }
.section-header.is-left      { text-align:start; margin-inline:0; padding-inline:0; }
.section-header.is-left h2,
.section-header.is-left .lede{ margin-inline:0; }

/* Takeaways under a block — secondary text, not a mini heading */
.section-note {
  font-family:var(--font-note);
  font-size:18px; line-height:1.5; font-weight:500;
  color:var(--text-muted); max-width:760px;
  margin:28px auto 0; text-align:center;
}
@media (max-width:768px) {
  .section-note { font-size:16px; line-height:1.45; max-width:100%; margin-top:22px; }
}


/* ── 09. Buttons ────────────────────────────────────────────────────────
   Three sizes. Text on a colored fill is white (§1.1a), 16px Bold minimum. */
.btn {
  --btn-h:48px;
  display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-2);
  height:var(--btn-h); padding-inline:var(--sp-6);
  border:0; border-radius:var(--radius-btn);
  font-size:16px; font-weight:700; line-height:1; white-space:nowrap;
  text-decoration:none; cursor:pointer; position:relative;
  transition:background var(--dur-fast) var(--ease),
             border-color var(--dur-fast) var(--ease),
             color var(--dur-fast) var(--ease);
}
.btn--medium { --btn-h:40px; padding-inline:var(--sp-4); }              /* reserved */
.btn--small  { --btn-h:32px; padding-inline:var(--sp-3);
               font-size:14px; border-radius:var(--radius-btn-sm); }

.btn__icon { width:var(--icon-lg); height:var(--icon-lg); flex-shrink:0; }
.btn--small .btn__icon { width:var(--icon-sm); height:var(--icon-sm); }

/* Touch target ≥44px on mobile without changing the visual size */
@media (max-width:768px) {
  .btn--small::after,
  .btn--medium::after { content:''; position:absolute; inset:-6px; }
}

.btn--primary { background:var(--cta); color:var(--cta-text); }
.btn--primary:hover { background:var(--cta-hover); }
.section--dark .btn--primary { background:var(--cta-on-dark); }
.section--dark .btn--primary:hover { background:var(--cta-on-dark-hover); }

/* Outline button — border --border #E6E8EC */
.btn--secondary {
  background:transparent; color:var(--text);
  border:2px solid var(--border);
}
.btn--secondary:hover { background:var(--bg-subtle); }
.section--dark .btn--secondary { color:var(--text-inverse); border-color:var(--n5); }
.section--dark .btn--secondary:hover { background:rgba(255,255,255,.08); }

.btn--ghost { background:transparent; color:var(--text); }
.btn--ghost:hover { background:var(--bg-subtle); }

.btn[disabled], .btn.is-disabled {
  background:var(--bg-sunken); color:var(--text-muted);
  border-color:var(--bg-sunken); cursor:not-allowed; pointer-events:none;
}
.btn.is-loading { color:transparent; pointer-events:none; }
.btn.is-loading::before {
  content:''; position:absolute; inset-block-start:50%; inset-inline-start:50%;
  width:18px; height:18px; margin:-9px 0 0 -9px;
  border:2px solid currentColor; border-block-start-color:var(--cta-text);
  border-radius:50%; color:rgba(255,255,255,.35);
  animation:swip-spin .7s linear infinite;
}
@keyframes swip-spin { to { transform:rotate(360deg); } }


/* ── 10. Cards ──────────────────────────────────────────────────────────
   No border and NO SHADOW — neither at rest nor on hover. Density: one idea. */
.card {
  background:var(--bg); border-radius:var(--radius-card);
  padding:var(--sp-6); display:flex; flex-direction:column; gap:var(--sp-3);
}
.card__header { display:flex; align-items:center; gap:var(--sp-3); }
.card__body   { flex:1; }
.card__footer { margin-block-start:var(--sp-2); }
.card__title  { font-size:20px; line-height:1.3; font-weight:600; margin:0; }
.card__text   { font-size:16px; line-height:1.55; color:var(--text-2); margin:0; max-width:none; }
.card__icon   { width:40px; height:40px; border-radius:var(--radius-inner);
                display:grid; place-items:center; background:var(--money-soft);
                color:var(--money-text); flex-shrink:0; }

.card--subtle   { background:var(--bg-subtle); }
.card--featured { border:2px solid var(--money-text); }
.card--dark     { background:var(--n2); color:var(--text-inverse); }
.card--dark .card__text { color:var(--n5); }
.card--dark .card__icon { background:rgba(38,200,120,.16); color:var(--money-on-dark); }

/* Clickable card: hover without lift — background, title, arrow */
a.card, .card--link { text-decoration:none; color:inherit; transition:background var(--dur-fast) var(--ease); }
a.card:hover, .card--link:hover { background:var(--bg-subtle); }
a.card:hover .card__title { color:var(--money-text); }
a.card .card__arrow { transition:transform var(--dur-fast) var(--ease); }
a.card:hover .card__arrow { transform:translateX(4px); }

@media (max-width:768px) { .card { padding:var(--sp-4); } }


/* ── 11. Tags and badges ────────────────────────────────────────────────
   The label color depends on whether there is a fill.
   The outline badge (.tag--outline) uses --border #E6E8EC, 2px.
   Border contrast is 1.23:1 — an accepted deviation, §1.1a; ignore it. */
.tag {
  display:inline-flex; align-items:center; gap:6px;
  padding:7px 10px; border-radius:var(--radius-tag);
  font-size:13px; font-weight:600; line-height:1; white-space:nowrap;
}
/* Colored fills — white label (§1.1a), from 13px SemiBold */
.tag--money    { background:var(--money-fill);    color:var(--text-on-fill); }
.tag--campaign { background:var(--campaign);      color:var(--text-on-fill); }
.tag--danger   { background:var(--danger);        color:var(--text-on-fill); }
.tag--blue     { background:var(--blue);          color:var(--text-on-fill); }
.tag--orange   { background:var(--orange-deep);   color:var(--text-on-fill); }
.section--dark .tag--money,
.card--dark    .tag--money { background:var(--money-on-dark); }

/* No fill — colored text */
.tag--soft    { background:var(--money-soft); color:var(--money-text); }
.tag--outline { background:transparent; color:var(--text); border:2px solid var(--border); }
.tag--subtle  { background:var(--bg-subtle); color:var(--text-2); }
/* glass — only inside a dark section or a dark card: label color #26C878 */
.tag--glass   { background:rgba(38,200,120,.16); color:var(--money-on-dark); }

/* Text tag: CAPS, no icons, no dashes */
.tag--text {
  background:none; padding:0; border:0;
  font-size:12px; font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--money-text);
}
.section--dark .tag--text { color:var(--money-on-dark); }

.tag--large { font-size:16px; font-weight:600; padding:8px 12px; }
@media (max-width:768px) {
  .tag--large { font-size:12px; padding:6px 10px; }
  .tag        { font-size:12px; }
}


/* ── 12. Metrics ────────────────────────────────────────────────────────
   On a light background a figure may only be green #00B868, --text #141416
   or --text-2 #353945. #007A45 has been retired and is not used.
   The one exception is .metric--danger #C41F1F, for drops and losses.
   #00B868 on light is 2.61:1 — an accepted deviation, §1.1a; ignore it. */
.metric {
  font-size:clamp(36px,4vw,56px); line-height:1;
  letter-spacing:-.02em; font-weight:700;
  color:var(--money-text); margin:0;
}
.metric--ink   { color:var(--text); }    /* #141416 — neutral figure */
.metric--muted { color:var(--text-2); }  /* #353945 — secondary figure */
.section--dark .metric, .card--dark .metric { color:var(--money-on-dark); }
.section--dark .metric--ink, .section--dark .metric--muted,
.card--dark .metric--ink, .card--dark .metric--muted { color:var(--text-inverse); }
.metric--danger { color:var(--danger-text); }
/* In a dark section #C41F1F gives 3.12:1 — drops use --red at 5.15:1.
   Order matters: this rule comes after the dark overrides of .metric */
.section--dark .metric--danger,
.card--dark .metric--danger { color:var(--danger-on-dark); }
.metric__note   { font-size:14px; line-height:1.45; color:var(--text-muted); margin:var(--sp-2) 0 0; }
.section--dark .metric__note, .card--dark .metric__note { color:var(--n5); }


/* ── 13. Forms ──────────────────────────────────────────────────────────── */
.field { display:block; margin-block-end:var(--sp-5); }
.field__label {
  display:block; font-size:14px; font-weight:600;
  margin-block-end:var(--sp-2); color:var(--text);
}
.field__label .req { color:var(--danger-text); }
.field__control {
  width:100%; height:48px; padding-inline:var(--sp-4);
  border:1px solid var(--border-control); border-radius:var(--radius-inner);
  background:var(--bg); color:var(--text);
  font-size:16px; line-height:1;
  transition:border-color var(--dur-fast) var(--ease);
}
textarea.field__control { height:auto; min-height:120px; padding-block:var(--sp-3); line-height:1.55; }
select.field__control   { appearance:none; padding-inline-end:var(--sp-10);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none' stroke='%23777E90' stroke-width='2'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right var(--sp-4) center; }
[dir="rtl"] select.field__control { background-position:left var(--sp-4) center; }

.field__control::placeholder { color:var(--text-muted); }
.field__control:hover  { border-color:var(--text-2); }
.field__control:focus-visible { border-color:var(--money-text); outline:3px solid var(--ring); outline-offset:2px; }
.field__control[readonly] { background:var(--bg-subtle); }
.field__control[disabled] { background:var(--bg-subtle); color:var(--text-muted); cursor:not-allowed; }

.field__hint  { display:block; margin-block-start:6px; font-size:14px; color:var(--text-muted); }
.field__error { display:none; margin-block-start:6px; font-size:14px; font-weight:500; color:var(--danger-text); }
.field.is-invalid .field__control { border-color:var(--danger-text); border-width:2px; }
.field.is-invalid .field__error   { display:block; }

/* Checkbox and radio.
   The selected element is filled with #00B868 via accent-color.
   Fill contrast is ignored: an accepted deviation, §1.1a */
.choice { display:flex; align-items:flex-start; gap:var(--sp-3); margin-block-end:var(--sp-3); cursor:pointer; }
.choice input { width:20px; height:20px; margin:2px 0 0; accent-color:var(--money-fill); flex-shrink:0; }
.choice span  { font-size:16px; line-height:1.45; }

/* Switch */
.switch { display:inline-flex; align-items:center; gap:var(--sp-3); cursor:pointer; }
.switch input { position:absolute; opacity:0; width:0; height:0; }
.switch__track {
  width:44px; height:24px; border-radius:99px; background:var(--n5);
  position:relative; transition:background var(--dur-fast) var(--ease); flex-shrink:0;
}
.switch__track::after {
  content:''; position:absolute; inset-block-start:2px; inset-inline-start:2px;
  width:20px; height:20px; border-radius:50%; background:var(--n9);
  transition:transform var(--dur-fast) var(--ease);
}
.switch input:checked + .switch__track { background:var(--money-fill); }
.switch input:checked + .switch__track::after { transform:translateX(20px); }
.switch input:focus-visible + .switch__track { outline:3px solid var(--ring); outline-offset:2px; }

.form-row { display:grid; gap:var(--sp-4); grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); }


/* ── 14. Accordion — native <details> ───────────────────────────────────── */
.accordion { border-block-end:1px solid var(--border); }
.accordion__item { border-block-start:1px solid var(--border); }
.accordion__item > summary {
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4);
  padding-block:var(--sp-5); cursor:pointer; list-style:none;
  font-size:20px; font-weight:600; line-height:1.3;
}
.accordion__item > summary::-webkit-details-marker { display:none; }
.accordion__item > summary::after {
  content:''; width:var(--icon-lg); height:var(--icon-lg); flex-shrink:0;
  background:currentColor; transition:transform var(--dur-fast) var(--ease);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 8l5 5 5-5' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 8l5 5 5-5' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E") center/contain no-repeat;
}
.accordion__item[open] > summary::after { transform:rotate(180deg); }
.accordion__item[open] > summary { color:var(--money-text); }
.accordion__body { padding-block-end:var(--sp-5); color:var(--text-2); max-width:75ch; }


/* ── 15. Tabs ─────────────────────────────────────────────────────────────
   The active tab: text and underline #00B868. Contrast ignored, §1.1a */
.tabs { display:block; }
.tabs__list {
  display:flex; gap:var(--sp-2); flex-wrap:wrap;
  border-block-end:1px solid var(--border); margin-block-end:var(--sp-6);
}
.tabs__tab {
  appearance:none; background:none; border:0; cursor:pointer;
  padding:var(--sp-3) var(--sp-4); margin-block-end:-1px;
  font-size:16px; font-weight:600; color:var(--text-muted);
  border-block-end:2px solid transparent;
  transition:color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.tabs__tab:hover { color:var(--text); }
.tabs__tab[aria-selected="true"] { color:var(--money-text); border-block-end-color:var(--money-text); }
.tabs__panel[hidden] { display:none; }


/* ── 16. Dialog — native <dialog> ───────────────────────────────────────── */
.dialog {
  border:0; padding:0; max-width:560px; width:calc(100% - var(--sp-8));
  border-radius:var(--radius-card); background:var(--bg); color:var(--text);
  box-shadow:var(--shadow-lg);
}
.dialog::backdrop { background:rgba(20,20,22,.5); }
.dialog__inner  { padding:var(--sp-8); }
.dialog__title  { font-size:24px; line-height:1.25; font-weight:700; margin:0 0 var(--sp-3); }
.dialog__text   { color:var(--text-2); margin:0 0 var(--sp-6); }
.dialog__actions{ display:flex; gap:var(--sp-3); flex-wrap:wrap; }
.dialog__close {
  position:absolute; inset-block-start:var(--sp-4); inset-inline-end:var(--sp-4);
  width:40px; height:40px; border:0; border-radius:var(--radius-inner);
  background:transparent; cursor:pointer; color:var(--text-muted);
  display:grid; place-items:center;
}
.dialog__close:hover { background:var(--bg-subtle); color:var(--text); }
@media (max-width:768px) { .dialog__inner { padding:var(--sp-6); } }


/* ── 17. Table ────────────────────────────────────────────────────────────
   Green figures use --money-text #00B868. Contrast ignored, §1.1a.
   Row dividers use --border #E6E8EC */
.table-wrap { overflow-x:auto; }
.table { width:100%; border-collapse:collapse; font-size:16px; text-align:start; }
.table caption { text-align:start; font-size:14px; color:var(--text-muted); margin-block-end:var(--sp-3); }
.table th, .table td { padding:var(--sp-4) var(--sp-4); text-align:start; border-block-end:1px solid var(--border); }
.table th {
  font-size:12px; font-weight:600; letter-spacing:.06em;
  text-transform:uppercase; color:var(--text-muted); white-space:nowrap;
}
.table tbody tr:hover { background:var(--bg-subtle); }
.table td.num { font-variant-numeric:tabular-nums; font-weight:600; white-space:nowrap; }
.table .is-money  { color:var(--money-text); font-weight:700; }   /* #00B868 */
.table .is-danger { color:var(--danger-text); font-weight:700; }  /* #C41F1F, always with a minus sign */
.section--dark .table .is-money  { color:var(--money-on-dark); }
.section--dark .table .is-danger { color:var(--danger-on-dark); }


/* ── 18. Tooltip and dropdown ─────────────────────────────────────────────
   Trigger buttons are outline .btn--secondary, lines --border #E6E8EC.
   The overlays themselves have no border: the shadow carries the layer. §1.1a,
   trigger border contrast ignored */
.tooltip { position:relative; display:inline-flex; }
.tooltip__bubble {
  position:absolute; inset-block-end:calc(100% + var(--sp-2)); inset-inline-start:50%;
  transform:translateX(-50%); z-index:var(--z-tooltip);
  padding:var(--sp-2) var(--sp-3); border-radius:var(--radius-tag);
  background:var(--n1); color:var(--text-inverse);
  font-size:14px; line-height:1.4; white-space:nowrap;
  box-shadow:var(--shadow-sm); opacity:0; pointer-events:none;
  transition:opacity var(--dur-fast) var(--ease);
}
.tooltip:hover .tooltip__bubble,
.tooltip:focus-within .tooltip__bubble { opacity:1; }

.dropdown { position:relative; }
.dropdown__menu {
  position:absolute; inset-block-start:calc(100% + var(--sp-2)); inset-inline-start:0;
  z-index:var(--z-dropdown); min-width:220px; padding:var(--sp-2);
  border-radius:var(--radius-inner); background:var(--bg);
  box-shadow:var(--shadow-lg);
}
.dropdown__menu[hidden] { display:none; }
.dropdown__item {
  display:block; width:100%; text-align:start;
  padding:var(--sp-3); border:0; border-radius:var(--radius-tag);
  background:none; cursor:pointer; font-size:16px; color:var(--text); text-decoration:none;
}
.dropdown__item:hover { background:var(--bg-subtle); }


/* ── 19. Utilities ──────────────────────────────────────────────────────── */
.visually-hidden {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;
}
.stack-2 { display:flex; flex-direction:column; gap:var(--sp-2); }
.stack-4 { display:flex; flex-direction:column; gap:var(--sp-4); }
.stack-6 { display:flex; flex-direction:column; gap:var(--sp-6); }
.row     { display:flex; gap:var(--sp-3); flex-wrap:wrap; align-items:center; }
.text-center { text-align:center; }
.text-start  { text-align:start; }
.mt-4 { margin-block-start:var(--sp-4); }
.mt-6 { margin-block-start:var(--sp-6); }
.mt-8 { margin-block-start:var(--sp-8); }


/* ── 20. v3.3.1 — fixes found while building the English homepage ─────────
   Conflict: §07 declares `.section--dark a { color:var(--money-on-dark) }` at
   specificity 0,1,1. That beats `.btn--primary` (0,1,0), so ANY link-button
   inside a dark section got green text on a green fill and the label became
   unreadable. <button> elements were unaffected.
   Below is the minimal fix: buttons get their own label color back.
   No tokens changed, so this is a minor version. */
.section--dark a.btn--primary,
.card--dark    a.btn--primary   { color:var(--cta-text); }
.section--dark a.btn--secondary,
.section--dark a.btn--ghost,
.card--dark    a.btn--secondary,
.card--dark    a.btn--ghost     { color:var(--text-inverse); }


/* ── 21. Tabs, vertical variant — v3.3.2 ──────────────────────────────────
   Added per §5.1 item 3: the existing component lacked a variant, so the
   variant lives here rather than inside a page. List on the left, panel on the
   right. The active tab has a 2px border; the accent comes from --tab-accent,
   defaulting to --money-text. Thin dividers between inactive tabs use ::after.
   Below 900px the layout collapses into ordinary horizontal tabs. */
.tabs--vertical {
  display:grid; gap:var(--sp-8); align-items:start;
  grid-template-columns:minmax(240px,340px) minmax(0,1fr);
}
/* All panels sit in the same grid cell, so the block's height equals the
   tallest panel and does not jump when switching. A hidden panel stays in
   flow, but visibility:hidden also removes it from the accessibility tree. */
.tabs--vertical .tabs__list  { grid-area:1 / 1; }
.tabs--vertical .tabs__panel { grid-area:1 / 2; align-self:stretch; }
.tabs--vertical .tabs__panel[hidden] { display:block; visibility:hidden; }
.tabs--vertical .tabs__list {
  flex-direction:column; align-items:stretch; flex-wrap:nowrap; gap:0;
  border-block-end:0; margin-block-end:0;
}
.tabs--vertical .tabs__tab {
  position:relative; margin:0; text-align:start;
  padding:var(--sp-5) var(--sp-4);
  border:2px solid transparent; border-radius:var(--radius-inner);
  font-size:20px; line-height:1.3; font-weight:600; color:var(--text-2);
}
.tabs--vertical .tabs__tab::after {
  content:''; position:absolute; inset-inline:var(--sp-4); inset-block-end:-1px;
  height:1px; background:var(--border);
}
.tabs--vertical .tabs__tab:last-child::after,
.tabs--vertical .tabs__tab[aria-selected="true"]::after,
.tabs--vertical .tabs__tab:has(+ [aria-selected="true"])::after { display:none; }
.tabs--vertical .tabs__tab:hover { color:var(--text); background:var(--bg-subtle); }
.tabs--vertical .tabs__tab[aria-selected="true"] {
  color:var(--text); background:var(--bg);
  border-color:var(--tab-accent, var(--money-text));
}
@media (max-width:900px) {
  .tabs--vertical { grid-template-columns:1fr; gap:var(--sp-6); }
  .tabs--vertical .tabs__list  { grid-area:1 / 1; }
  .tabs--vertical .tabs__panel { grid-area:2 / 1; }
  .tabs--vertical .tabs__list {
    flex-direction:row; flex-wrap:wrap; gap:var(--sp-2);
    border-block-end:1px solid var(--border);
  }
  .tabs--vertical .tabs__tab {
    padding:var(--sp-3) var(--sp-4); font-size:16px;
    border:0; border-block-end:2px solid transparent; border-radius:0;
    margin-block-end:-1px;
  }
  .tabs--vertical .tabs__tab::after { display:none; }
  .tabs--vertical .tabs__tab[aria-selected="true"] {
    background:none; border-block-end-color:var(--tab-accent, var(--money-text));
  }
}


/* ── 22. v3.3.3 — --quiet darkened ────────────────────────────────────────
   Found while reviewing the English homepage: #6B7280 met the 4.5:1 minimum
   only on pure white. On --bg-subtle (the background of entire sections) it
   gave 4.43, on --money-soft 4.46, on --bg-sunken 3.94 — so .small,
   .section-note, .metric__note and inactive tabs on light grey sections all
   failed. #5F6875 passes on all four surfaces and still reads as quiet.
   A token changed, not the markup: minor version, no markup changes. */


/* ── 23. v3.3.4 — burger touch target at tablet widths ────────────────────
   Found during the pre-release check of the English homepage. The touch-target
   expansion (§09) was limited to max-width:768px, while .nav-toggle ("Menu")
   appears from max-width:1024px. Between 769 and 1024px the button had no
   ::after at all: its real tap area equalled its visual 32px instead of 44px.
   The breakpoint is now aligned with where the button actually appears.
   inset:-6px is kept deliberately: 32+12=44px, and the gap between Menu and
   Sign in is var(--sp-3)=12px, so adjacent tap areas meet but never overlap.
   The visual size of the buttons is unchanged. */
@media (max-width:1024px) {
  .btn--small::after,
  .btn--medium::after { content:''; position:absolute; inset:-6px; }
}


/* ── 24. v3.3.5 — hero H1 on narrow phones ────────────────────────────────
   Found during the pre-release check of the English homepage. The h1 scale is
   clamp(52px,5vw,72px), so on any phone the 52px floor applies. With the new
   SEO headline ("The AI loyalty platform that grows revenue and cuts losses")
   the H1 took 371px at 375px wide and pushed the primary CTA below the fold:
   on an iPhone SE (667px) the button was not visible without scrolling.
   The floor is lowered ONLY for .hero-title and ONLY below 400px. Other h1s,
   tablet and desktop are untouched — the shared §1.3 scale does not change. */
@media (max-width:399px) {
  .hero-title { font-size:40px; line-height:1.05; }
}


/* ── 25. v3.3.6 — auto-fit grids would not shrink on phones ───────────────
   Found on the English homepage: the "Real personalization" block spilled out
   of its white panel. The cause is common to every auto-fit grid in the
   system — minmax(Npx,1fr) sets a hard minimum of N, so once the container is
   narrower than N the column stops shrinking and overflows its parent. At
   320px .grid-2 spilled by up to 96px. min(Npx,100%) lowers that floor to the
   container width. Desktop behaviour is unchanged: there the container is
   always wider than N. */
.grid-2   { grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr)); }
.grid-3   { grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr)); }
.grid-4   { grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr)); }
.form-row { grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr)); }


/* ── 26. v3.3.7 — --font-note fell back to a system face ──────────────────
   --font-note declares 'Nunito Sans', but no NunitoSans woff2 exists in the
   project, so the three .section-note paragraphs on the homepage rendered in
   the OS sans instead of Inter — visibly a different typeface from everything
   around them. Pointed at the base stack so the page ships in one typeface and
   downloads no second family. If the two-typeface design is intended, add
   assets/fonts/NunitoSans-Medium.woff2, restore the @font-face for it and
   revert this block. */
:root { --font-note: var(--font-base); }
