/* =========================================================================
   AVH Accounting — Modern Fintech Editorial
   Warm off-white canvas · huge medium-weight type · hairline grids ·
   one acid-lime accent · dark-green inverse section · whisper motion.
   (System: RAMP-STYLE-GUIDE.md from the design handoff.)
   ========================================================================= */

/* ---- Fonts (self-hosted, no CDN waterfall) ---- */
@font-face {
  font-family: 'Instrument Sans';
  src: url("/static/fonts/instrument-sans.e35fad09c70b.woff2") format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url("/static/fonts/instrument-sans-ext.e2385a017626.woff2") format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Cyrillic falls through to Manrope (closest self-hosted grotesque) */
/* The unicode-range is what keeps this face OFF Armenian pages. Without it
   the face is a candidate for ANY codepoint, so on hy the browser downloads
   all 24.9 KB looking for Armenian glyphs it does not contain, then falls
   through to Noto Sans Armenian anyway (expert review 2026-07-28, 1.2).
   Latin never regresses: Instrument Sans comes first in --sans and covers
   the same range; Cyrillic keeps its own face below. */
@font-face {
  font-family: 'Manrope';
  src: url("/static/fonts/manrope.938c6e8019b6.woff2") format('woff2');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Manrope';
  src: url("/static/fonts/manrope-cyr.e58febde317b.woff2") format('woff2');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* Armenian */
@font-face {
  font-family: 'Noto Sans Armenian';
  src: url("/static/fonts/noto-sans-armenian.f062c0821106.woff2") format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0530-058F, U+FB13-FB17;
}

/* ---- Serif display voice (editorial accent — headings/quotes only) ----
   Cormorant carries latin + cyrillic; Noto Serif Armenian carries hy. The
   browser resolves each script by unicode-range, so one --serif stack works
   across all three languages. Cormorant has NO Armenian glyphs — hy falls
   through to Noto Serif Armenian. */
@font-face {
  font-family: 'Cormorant Garamond';
  src: url("/static/fonts/cormorant-garamond.c47ff12887a3.woff2") format('woff2');
  font-weight: 400 700; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: 'Cormorant Garamond';
  src: url("/static/fonts/cormorant-garamond-italic.3e2c4175a96d.woff2") format('woff2');
  font-weight: 400 700; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: 'Cormorant Garamond';
  src: url("/static/fonts/cormorant-garamond-cyr.e1df04190d1b.woff2") format('woff2');
  font-weight: 400 700; font-style: normal; font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Cormorant Garamond';
  src: url("/static/fonts/cormorant-garamond-cyr-italic.b554abc2d050.woff2") format('woff2');
  font-weight: 400 700; font-style: italic; font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Noto Serif Armenian';
  src: url("/static/fonts/noto-serif-armenian.ec389a2f499b.woff2") format('woff2');
  font-weight: 100 900; font-style: normal; font-display: swap;
  unicode-range: U+0530-058F, U+FB13-FB17;
}

/* ---- Tokens ---- */
:root {
  --bg:            #F8F7F4;   /* warm off-white, never pure white */
  --bg-elevated:   #FFFFFF;
  --bg-hover:      #F1F0EB;
  --bg-inverse:    #1C2B21;   /* near-black green for inverse sections */

  --ink:           #1A1A18;
  --ink-secondary: #6E6C66;
  --ink-inverse:   #F4F3EF;
  --ink-inverse-2: rgba(244, 243, 239, 0.6);

  --hairline:      #E4E2DC;   /* decorative separators — rules between rows/sections */
  --hairline-inv:  rgba(244, 243, 239, 0.2);
  /* The ONLY visible boundary of an interactive control (inputs, chips, tabs,
     ghost buttons). WCAG 1.4.11 asks 3:1 against the adjacent surface, and
     --hairline was doing that job at 1.21:1 (expert review 2026-07-24, C1).
     Measured: 3.21:1 on --bg, 3.44:1 on --bg-elevated, 3.02:1 on --bg-hover.
     (The review proposed #B7B3A9 — that is only 1.95:1, so it is NOT used.)
     Keep --hairline for rules that carry no meaning on their own. */
  --border-interactive: #8E8A80;

  /* Error red, three tokens instead of the five undesigned hexes that had
     accumulated — #8A2E2E, #6F2424, #B95C4F, #D8B4B0, #E8CFCA (expert
     review 2026-07-24, 2.6). Measured on --bg: --danger 7.81:1 (text),
     --danger-border 4.16:1 (clears the 3:1 that a control's only boundary
     needs), --danger text on --danger-bg 7.07:1. The dropped #D8B4B0 was
     1.77:1 — a red that only reads as red to someone who can see it. */
  --danger:        #8A2E2E;
  --danger-border: #B95C4F;
  --danger-bg:     #F7E9E7;

  --accent:        #DFF250;   /* the single acid accent — full strength ONLY at chip scale / 1-3px lines */
  --accent-ink:    #1A1A18;
  --accent-soft:   rgba(223, 242, 80, 0.65); /* marker ink — paper shows through */
  --accent-hover:  #E9FA6E;
  /* Selection = the marker metaphor made live: a translucent lime stroke.
     No `color` declared — text keeps its own color. Dark sections keep the
     pale ink wash (lime-on-lime type would vanish there). */
  --selection:     rgba(223, 242, 80, 0.45);
  --selection-inv: rgba(244, 243, 239, 0.20);

  --sans: 'Instrument Sans', 'Manrope', 'Noto Sans Armenian', 'Helvetica Neue', -apple-system, sans-serif;
  --serif: 'Cormorant Garamond', 'Noto Serif Armenian', Georgia, 'Times New Roman', serif;
  --mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, 'Noto Sans Armenian', monospace;

  --maxw: 1280px;
  --gutter: 40px;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---- Reset-ish ---- */
* { box-sizing: border-box; }
html {
  scroll-behavior: smooth;
  scroll-padding-top: 80px; /* anchors clear the fixed 64px header */
  interpolate-size: allow-keywords; /* lets ::details-content animate to auto */
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
img, video { max-width: 100%; height: auto; display: block; }
a, button, input, textarea { touch-action: manipulation; }
::selection { background: var(--selection); }
.inverse ::selection { background: var(--selection-inv); }

h1, h2, h3 { font-weight: 500; margin: 0; }

/* Visible keyboard focus */
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 4px;
}
.btn:focus-visible, .lang-current:focus-visible { outline-offset: 2px; border-radius: 999px; }
/* On dark (.inverse) surfaces the near-black --ink outline is invisible — flip to light. */
.inverse :focus-visible { outline-color: var(--ink-inverse); }

/* Skip link */
.skip-link {
  position: fixed; top: -100px; left: 1rem; z-index: 100;
  padding: 0.8rem 1.4rem; border-radius: 999px;
  background: var(--ink); color: var(--bg); font-weight: 500; font-size: 0.9rem;
  transition: top 0.25s var(--ease-out);
}
.skip-link:focus { top: 1rem; }

.wrap { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }

/* Diagonal hairline stripes — the page breathes (hero + inverse only).
   Drawn on an oversized pseudo-element and moved with transform so the
   drift runs on the compositor, not as endless main-thread repaints. */
.striped { position: relative; overflow: hidden; }
.striped > * { position: relative; z-index: 1; }
.striped::before {
  content: "";
  position: absolute;
  inset: 0 0 0 -240px;
  background-image: repeating-linear-gradient(115deg,
    rgba(26, 26, 24, 0.05) 0 1px, transparent 1px 16px);
  animation: stripeDrift 24s linear infinite;
  pointer-events: none;
}
.striped--inverse::before {
  background-image: repeating-linear-gradient(115deg,
    rgba(244, 243, 239, 0.05) 0 1px, transparent 1px 16px);
  animation-duration: 32s;
}
@keyframes stripeDrift { to { transform: translateX(240px); } }
@keyframes marquee { to { transform: translateX(-50%); } }
/* The drift used to be killed outright on touch / small screens. Owner
   report 2026-07-23: the phone read dead next to the desktop, and a surface
   that lives is the whole brand. It is a transform-only animation (GPU
   composited — no layout, no paint), so instead of dropping it we pause it
   while the section is off-screen: the compositor only works for texture
   the visitor can actually see. prefers-reduced-motion still kills it
   outright below (line ~1797). */
.striped.is-offscreen::before { animation-play-state: paused; }
.marquee-track.is-offscreen { animation-play-state: paused; }

/* ---- Utility: eyebrow / mono label ---- */
.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary);
  font-weight: 500;
}

.section-head { margin-bottom: 56px; }
.section-head .eyebrow { display: block; margin-bottom: 20px; }
.section-head h1,
.section-head h2 {
  font-size: clamp(36px, 4.5vw, 56px);
  letter-spacing: -0.03em;
  line-height: 1.05;
  max-width: 640px;
  text-wrap: balance;
  overflow-wrap: break-word; /* 15–20-glyph Armenian words vs 335px screens */
}
.section-head p {
  color: var(--ink-secondary);
  font-size: 17px;
  max-width: 480px;
  margin: 20px 0 0;
}
/* Two-column head on wide screens. Eleven heads in a row ran label → 56px
   heading → 17px intro down the left edge, so the right half of a 1200px
   container sat empty eleven times (expert review 2026-07-24, 2.1). The intro
   moves across and its last line lands on the heading's bottom edge.
   Heads WITHOUT an intro (process, gallery, clients, team) stay single-column
   by themselves — that alternation is the variation the review asked for,
   and it costs no markup. Rows are explicit: several heads have no eyebrow,
   and auto-placement would then drop the intro a row below the heading. */
@media (min-width: 1100px) {
  .section-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.72fr);
    column-gap: 80px;
    align-items: end;
  }
  .section-head > .eyebrow { grid-area: 1 / 1; }
  .section-head > h1,
  .section-head > h2 { grid-area: 2 / 1; }
  .section-head > p { grid-area: 2 / 2; margin: 0; }
  /* A "last updated" date is not an intro — it belongs under its own title. */
  .section-head > p.legal-updated { grid-area: 3 / 1; margin: 20px 0 0; }
  /* Nor is a cross-link to the sibling calendar. The cell above holds ONE
     paragraph by design — the rule is written that way so a head without an
     eyebrow does not drop its intro a row — so a second <p> lands on top of
     the first rather than after it. /tax-calendar/ was the first page to have
     two, and at >=1100px its "looking for working days?" line sat across the
     intro (found on prod 2026-09-03, the day the page was opened).
     Explicit like .legal-updated above, not `p ~ p`: .calc-print-brand is a
     <p> too and it precedes the intro, so a sibling selector moves the wrong
     paragraph. */
  .section-head > p.tc-sibling { grid-area: 3 / 2; margin: 12px 0 0; }
}

/* Accent word inside headlines (*word* in the admin).
   A highlighter stroke behind the lower x-height — not a full-height slab,
   so it never swallows a whole line or opens gaps before punctuation. */
/* Highlighter marker. Geometry via custom props so per-font/per-language tuning
   is a one-line override. The bar covers lower-x-height→baseline (a real marker
   stroke), not mid-glyph→descenders; translucent ink lets the paper through.
   padding+negative margin give a small stroke overhang without moving text —
   cloned per wrapped line by box-decoration-break. */
.gold {
  --marker-h: 0.42em;
  --marker-y: 68%;
  background: linear-gradient(var(--accent-soft), var(--accent-soft))
              0 var(--marker-y) / 100% var(--marker-h) no-repeat;
  padding-inline: 0.1em;
  margin-inline: -0.1em;
  color: inherit;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
/* Heading accent words: serif italic against the sans heading — the signature
   contrast, carried by type alone. The lime marker is rationed to ONE moment
   per page: the "30 seconds" promise (#digital), proven live by the chat demo
   beside it — everywhere else color stays on CTAs. font-synthesis:none means
   hy (Noto Serif Armenian, no italic face) renders upright while en/ru get
   true Cormorant italic. */
.hero h1 .gold, h2 .gold {
  font-family: var(--serif); font-style: italic; font-synthesis: none;
  font-size: 1.05em;
  background: none;
  padding-inline: 0; margin-inline: 0;
}
/* --marker-draw (0→1, default 1) "draws" the stroke on scroll; without JS,
   without @property support, or with reduced motion the marker simply
   renders complete. See the @property block near the drawn hairlines. */
#digital h2 .gold {
  background: linear-gradient(var(--accent-soft), var(--accent-soft))
              0 var(--marker-y) / calc(var(--marker-draw, 1) * 100%) var(--marker-h) no-repeat;
  padding-inline: 0.1em; margin-inline: -0.1em;
}

/* =========================================================================
   Header — fixed; transparent at the very top, gains blur+hairline on scroll
   ========================================================================= */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  height: 64px;
  display: flex;
  align-items: center;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 250ms ease, border-color 250ms ease, color 250ms ease;
}
.header-progress {
  position: absolute; left: 0; bottom: -1px; height: 1px; width: 100%;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
  opacity: 0; transition: opacity 250ms ease;
}
.site-header.is-scrolled .header-progress { opacity: 1; }
.site-header.is-scrolled, .site-header.open {
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  background: rgba(248, 247, 244, 0.85);
  border-bottom-color: var(--hairline);
}
/* Inverse state — set from site.js while a dark panel covers the header's
   middle line. The light band over a dark section read as a muddy grey
   stripe and sliced the top off the footer CTA's 121px heading, the best
   piece of type on the site (expert review 2026-07-24, 2.7).

   :not(.open) throughout: the open mobile menu hangs a light panel off this
   same element, so inverting the links there would put pale ink on paper. */
.site-header.is-over-dark:not(.open) { color: var(--ink-inverse); }
.site-header.is-over-dark.is-scrolled:not(.open) {
  background: rgba(28, 43, 33, 0.85);
  border-bottom-color: var(--hairline-inv);
}
.site-header.is-over-dark:not(.open) .brand { color: var(--ink-inverse); }
.site-header.is-over-dark:not(.open) .brand .mark { background: var(--ink-inverse); color: var(--bg-inverse); }
.site-header.is-over-dark:not(.open) .nav a { color: var(--ink-inverse-2); }
.site-header.is-over-dark:not(.open) .nav a:hover,
.site-header.is-over-dark:not(.open) .nav a.active { color: var(--ink-inverse); }
.site-header.is-over-dark:not(.open) .menu-toggle { color: var(--ink-inverse); }
/* 0.45 white over --bg-inverse measures 3.9:1 — a control border still has to
   clear 3:1 on the surface it sits on (same rule as --border-interactive). */
.site-header.is-over-dark:not(.open) .lang-current {
  color: var(--ink-inverse); border-color: rgba(244, 243, 239, 0.45);
}
.site-header.is-over-dark:not(.open) .lang-current:hover { background: rgba(244, 243, 239, 0.1); }
.site-header.is-over-dark:not(.open) .btn-primary { background: var(--ink-inverse); color: var(--ink); }
.site-header.is-over-dark:not(.open) .btn-primary:hover { background: #FFFFFF; }
.header-inner {
  max-width: var(--maxw); width: 100%;
  margin-inline: auto; padding-inline: var(--gutter);
  display: flex; align-items: center; gap: 32px;
}
.brand { display: flex; align-items: center; gap: 10px; font-weight: 600; font-size: 18px; letter-spacing: -0.02em; white-space: nowrap; }
/* <picture> is an inline wrapper — make it a transparent flex item so the
   mark keeps sitting on the same optical line as the wordmark. */
.brand picture { display: flex; flex: none; }
.brand img { height: 28px; width: auto; }
.brand .mark {
  width: 28px; height: 28px; border-radius: 8px;
  display: grid; place-items: center;
  background: var(--ink); color: var(--bg);
  font-weight: 600; font-size: 0.85rem;
}
.nav { display: flex; align-items: center; gap: 24px; }
/* nowrap: with 7 items a squeezed flex line breaks a link ("Sign in",
   "Ассистент 24/7") into two lines before the burger breakpoint kicks in. */
.nav a { font-size: 14px; font-weight: 500; color: var(--ink-secondary); transition: color 150ms ease; white-space: nowrap; }
.nav a:hover { color: var(--ink); text-decoration: none; }
.nav a.active { color: var(--ink); box-shadow: 0 3px 0 -1px var(--accent); }
.header-right { margin-left: auto; display: flex; align-items: center; gap: 16px; }

/* Buttons — pills */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 14px 24px;
  /* 1.2, not 1 — long Armenian labels wrap to two lines inside the pill */
  font-family: var(--sans); font-size: 15px; font-weight: 500; line-height: 1.2;
  border-radius: 999px; border: 1px solid transparent; cursor: pointer;
  transition: background 150ms ease, transform 150ms ease, border-color 150ms ease;
}
.btn:hover { text-decoration: none; }
.btn-primary { background: var(--ink); color: var(--bg); }
.btn-primary:hover { background: #000; transform: translateY(-1px); }
.btn-primary:active { transform: translateY(0); }
.btn-ghost { background: var(--bg-elevated); color: var(--ink); border-color: var(--border-interactive); }
.btn-ghost:hover { background: var(--bg-hover); transform: translateY(-1px); }
.btn .chip {
  background: var(--accent); color: var(--accent-ink);
  border-radius: 999px; font-size: 11px; font-weight: 600; padding: 3px 8px;
}
.btn .arrow { transition: transform 200ms ease; }
.btn:hover .arrow { transform: translateX(3px); }
.nav-cta { padding: 10px 20px; font-size: 14px; white-space: nowrap; }

.menu-toggle {
  display: none; background: none; border: 0; color: var(--ink); cursor: pointer;
  min-width: 44px; min-height: 44px;
}
.menu-toggle .bar-top, .menu-toggle .bar-bottom {
  transition: transform 200ms ease;
  transform-origin: 12px 12px;
}
.site-header.open .menu-toggle .bar-top { transform: translateY(4px) rotate(45deg); }
.site-header.open .menu-toggle .bar-bottom { transform: translateY(-4px) rotate(-45deg); }

/* CTA + language row shown only inside the open mobile menu */
.nav-mobile-extra { display: none; }
.nav-mobile-langs { display: flex; gap: 8px; }
.nav-mobile-langs a {
  display: inline-flex; align-items: center; text-decoration: none;
  min-height: 44px; padding: 8px 16px; border-radius: 999px;
  background: transparent; border: 1px solid var(--border-interactive);
  color: var(--ink-secondary);
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; font-weight: 500;
  cursor: pointer;
}
.nav-mobile-langs a.active { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.nav-mobile-phone {
  display: block; min-height: 44px; padding: 10px 0;
  font-family: var(--mono); font-size: 15px; letter-spacing: 0.04em;
  color: var(--ink); text-decoration: none;
}

/* ---- Language switcher (mono codes, no flag colors) ---- */
.lang-switch { position: relative; }
.lang-current {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-radius: 999px;
  background: transparent; border: 1px solid var(--border-interactive);
  color: var(--ink); font-family: var(--mono); font-size: 12px; font-weight: 500; letter-spacing: 0.06em;
  cursor: pointer; transition: background 150ms ease, border-color 150ms ease;
}
.lang-current:hover { background: var(--bg-hover); }
.lang-current .chev { transition: transform 200ms ease; }
.lang-switch.open .lang-current .chev { transform: rotate(180deg); }
.lang-menu {
  position: absolute; top: calc(100% + 10px); right: 0; min-width: 170px;
  padding: 4px; border-radius: 8px;
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  box-shadow: 0 12px 32px -16px rgba(26, 26, 24, 0.18);
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity 200ms ease, transform 200ms ease, visibility 200ms;
  z-index: 60;
}
.lang-switch.open .lang-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.lang-menu a {
  display: flex; align-items: center; gap: 10px; width: 100%;
  text-decoration: none;
  padding: 10px 12px; border: 0; border-radius: 6px;
  background: transparent; color: var(--ink-secondary);
  font-family: var(--sans); font-size: 14px; font-weight: 500; text-align: left; cursor: pointer;
  transition: background 150ms ease, color 150ms ease;
}
.lang-menu a:hover { background: var(--bg-hover); color: var(--ink); }
.lang-menu a.active { color: var(--ink); }
.lang-menu a.active::after { content: '✓'; margin-left: auto; font-size: 0.8rem; }
.lang-menu .lang-code {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  color: var(--ink-secondary); min-width: 34px;
}

/* =========================================================================
   Hero
   ========================================================================= */
.hero { border-bottom: 1px solid var(--hairline); }
.hero-inner { padding-block: 176px 96px; }
@media (min-width: 1101px) {
  .hero-inner {
    display: grid;
    grid-template-columns: 1.1fr 0.9fr;
    gap: 64px;
    align-items: center;
  }
  .hero-media { grid-column: 1 / -1; }
}

/* Hero chat — the killer feature, drawn in hairlines. A messenger window:
   header (avatar · name · online) + a live dialog that plays out in beats. */
.hero-chat { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.chat-caption {
  margin: 0;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
}
.chat-app {
  width: min(420px, 100%);
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 24px 48px -32px rgba(26, 26, 24, 0.25);
}
.chat-app-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--hairline);
  background: var(--bg);
}
.chat-avatar {
  width: 34px; height: 34px; border-radius: 10px; flex: none;
  display: grid; place-items: center;
  background: var(--ink); color: var(--bg);
  font-weight: 600; font-size: 15px;
}
.chat-app-id { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.chat-app-name { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }
.chat-app-status {
  display: flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
}
.status-dot {
  width: 6px; height: 6px; border-radius: 999px;
  background: var(--accent);
  outline: 3px solid rgba(223, 242, 80, 0.35);
}
.chat-app-net {
  margin-left: auto;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
}
.chat-app-body {
  padding: 20px 18px 22px;
  display: flex; flex-direction: column; gap: 10px;
  font-family: var(--mono); font-size: 12.5px;
}
.chat-app .chat-bot { background: var(--bg); }
.chat-followup { width: auto; max-width: 85%; }
.chat-time {
  display: block; margin-top: 6px;
  font-size: 10px; letter-spacing: 0.05em;
  color: var(--ink-secondary);
}
.chat-user .chat-time { color: var(--ink-inverse-2); text-align: right; }

/* Typing indicator — lives between beats, then yields to the reply */
.chat-typing {
  align-self: flex-start;
  display: flex; gap: 4px;
  padding: 12px 14px;
  background: var(--bg);
  border: 1px solid var(--hairline);
  border-radius: 12px; border-bottom-left-radius: 4px;
}
.chat-typing span {
  width: 5px; height: 5px; border-radius: 999px;
  background: var(--ink-secondary);
  animation: typingPulse 1s ease-in-out infinite;
}
.chat-typing span:nth-child(2) { animation-delay: 0.15s; }
.chat-typing span:nth-child(3) { animation-delay: 0.3s; }
/* Hero typing dots are decorative and never hidden — let them settle instead
   of pulsing forever. The interactive playground keeps the infinite loop. */
.hero .chat-typing span { animation-iteration-count: 3; }

/* Sequence: base state is visible (reduced-motion still shows the finished
   dialog); the keyframes' backwards fill supplies the hidden start. */
.chat-seq {
  animation: msgIn 0.5s var(--ease-out) both;
  animation-delay: calc(0.4s + var(--seq, 0) * 1.1s);
}
.chat-typing.chat-seq {
  animation: typingLife 1.6s var(--ease-out) both;
  animation-delay: 1.2s;
}
@keyframes msgIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes typingLife {
  0%   { opacity: 0; transform: translateY(10px); }
  12%  { opacity: 1; transform: translateY(0); }
  82%  { opacity: 1; }
  100% { opacity: 0; }
}
@keyframes typingPulse { 50% { opacity: 0.3; } }

@media (max-width: 1100px) {
  /* The chat is the pitch, not decoration — mobile gets it too */
  .hero-chat { align-items: flex-start; margin-top: 48px; }
  .chat-app { width: min(400px, 100%); }
}

/* Hero value panel — occupies the chat's old elevated slot (the one deep-shadow
   surface on the page). Supporting content, NOT a CTA: the single price action
   is the hero button on the left, so this stays non-interactive. */
.hero-offer { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.offer-card {
  width: min(420px, 100%);
  /* Room at the foot for the tear line. */
  padding: 28px 28px 40px;
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  box-shadow: 0 24px 48px -32px rgba(26, 26, 24, 0.25);
  color: var(--ink);
}
/* The whole home page is typography and hairlines — not one object on it
   (expert review 2026-07-28, 5.5, "$10K gate" point 5: imagery with intent).
   The cheapest honest object is the one already here: this card, given the
   texture of a document rather than a web panel. A ruled header and a
   torn-off bottom edge, both drawn in the system's own hairline. No invented
   figures and no new claims — a card that LOOKS like a report it is not
   would be a lie told in CSS. */
.offer-card { position: relative; }
.offer-card::after {
  /* Perforation: a dashed tear line just above the lower edge. */
  content: ""; position: absolute; left: 14px; right: 14px; bottom: 12px;
  border-top: 1px dashed var(--hairline);
}
.offer-eyebrow {
  display: block;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
  padding-bottom: 12px;
  border-bottom: 1px solid var(--hairline);
}
.offer-title {
  margin: 12px 0 18px;
  font-size: 24px; line-height: 1.25; letter-spacing: -0.01em; font-weight: 600;
}
.offer-points { margin: 0; padding: 0; list-style: none; }
.offer-points li {
  position: relative;
  padding: 12px 0 12px 26px;
  border-top: 1px solid var(--hairline);
  font-size: 14.5px; color: var(--ink-secondary);
}
.offer-points li::before { content: "✓"; position: absolute; left: 2px; color: var(--ink); }
@media (max-width: 1100px) {
  .hero-offer { align-items: flex-start; margin-top: 48px; }
  .offer-card { width: min(400px, 100%); }
}
.hero .ticker-line {
  font-family: var(--mono);
  font-size: 12px; letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary);
  margin-bottom: 28px;
}
.hero h1 {
  font-size: clamp(56px, 8vw, 104px);
  letter-spacing: -0.04em;
  line-height: 0.98;
  max-width: 900px;
  text-wrap: balance;
  /* 15–20-glyph Armenian words vs a 350px content box at 390px viewport:
     without this the last word clips under body's overflow-x:hidden
     (same fix as .section-head h1/h2) */
  overflow-wrap: break-word;
}
.hero .lead {
  font-size: 18px; line-height: 1.55; color: var(--ink-secondary);
  margin: 28px 0 36px; max-width: 480px;
}
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 20px; }
.hero-actions .btn-secondary {
  font-size: 15px; font-weight: 500; color: var(--ink);
  /* padding-block lifts the tap target to ~44px (WCAG 2.5.8) without moving
     the underline, which is anchored to the text baseline */
  padding-block: 11px;
  text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--hairline);
  transition: text-decoration-color 150ms ease;
}
.hero-actions .btn-secondary:hover { text-decoration-color: var(--ink); }
.hero-trust {
  margin-top: 20px;
  font-family: var(--mono);
  font-size: 12px; letter-spacing: 0.04em;
  color: var(--ink-secondary);
}

/* Optional admin-uploaded hero media, framed under the text */
.hero-media {
  margin-top: 72px;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-elevated);
}
.hero-media img, .hero-media video { width: 100%; max-height: 640px; object-fit: cover; }

/* =========================================================================
   Client marquee — labelled strip with soft edge fades
   ========================================================================= */
.marquee {
  border-bottom: 1px solid var(--hairline);
  padding: 24px var(--gutter);
  display: flex; align-items: center; gap: 40px;
  overflow: hidden;
}
.marquee-label { flex: none; }
.marquee-viewport {
  /* min-width: 0 — the track is width:max-content, so without it the
     viewport refuses to shrink below the full strip and pushes the pause
     button out of the row (and off the left edge). */
  overflow: hidden; flex: 1; min-width: 0;
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee-track {
  display: flex; gap: 72px; width: max-content; align-items: center;
  animation: marquee var(--marquee-dur, 30s) linear infinite;
}
.marquee:hover .marquee-track { animation-play-state: paused; }
/* Explicit pause (WCAG 2.2.2) — hover is a mouse-only affordance. The
   button exists only when JS can wire it; reduced motion kills the
   animation outright, so the control has nothing left to toggle. */
.marquee-pause { display: none; }
.js .marquee-pause {
  flex: none; width: 44px; height: 44px; padding: 0;
  display: grid; place-items: center;
  border: 1px solid var(--border-interactive); border-radius: 999px;
  background: transparent; color: var(--ink-secondary); cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.js .marquee-pause:hover { background: var(--bg-hover); color: var(--ink); }
.marquee-pause .marquee-pause-tri { display: none; }
.marquee.is-paused .marquee-track { animation-play-state: paused; }
.marquee.is-paused .marquee-pause .marquee-pause-bar { display: none; }
.marquee.is-paused .marquee-pause .marquee-pause-tri { display: block; }
.marquee .logo {
  font-size: 20px; font-weight: 600; letter-spacing: -0.02em;
  color: var(--ink); opacity: 0.62; white-space: nowrap;
}
.marquee .logo img { height: 28px; width: auto; filter: grayscale(1); opacity: 0.7; }

/* =========================================================================
   Sections — hairline-separated so whitespace reads as designed, not empty
   ========================================================================= */
.block { padding-block: 96px; border-top: 1px solid var(--hairline); }
.block--tight { padding-block: 72px; }
/* 72 / 96 / 128 instead of one flat measure — the sections that carry the
   decision (price, contact) get room around them (expert review 2.1).
   Wide screens only: the phone page was just cut from 20.5 to 16.1 screens
   (P1-A) and does not give that back for desktop breathing room. */
@media (min-width: 1100px) { .block--airy { padding-block: 128px; } }
.hero + .marquee, .marquee + .block, .hero + .block { border-top: 0; }

/* Monthly-report demo — an editorial "ledger sheet" (illustrative). */
.report-sheet {
  max-width: 560px; margin: 0 auto;
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  border-radius: 14px;
  padding: 36px 40px 28px;
}
.report-section {
  font-family: var(--mono);
  font-size: 11px; letter-spacing: 0.1em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary);
  margin: 26px 0 12px; padding-bottom: 8px;
  border-bottom: 1px solid var(--hairline);
}
.report-section:first-child { margin-top: 0; }
.report-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: 7px 0; font-size: 15px;
}
/* The label is the side that gives. A flex item will not shrink below its
   longest word, and Armenian labels here run 20+ glyphs, so the amount was
   pushed 9px into the sheet's own padding on a phone (audit 2026-07-25).
   The number keeps nowrap — a price broken across lines is worse than a
   tight one. */
.report-row > :first-child { min-width: 0; overflow-wrap: anywhere; }
.report-val { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.report-total { margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--ink); font-weight: 600; }
.report-total .report-val { font-size: 17px; }
.report-subline {
  font-family: var(--mono); font-size: 12px; color: var(--ink-secondary);
  padding: 2px 0 6px;
}
.report-note {
  margin-top: 18px; padding: 12px 14px;
  background: var(--bg-hover); border-radius: 8px;
  font-size: 14px; line-height: 1.5; color: var(--ink);
}
.report-foot {
  margin: 20px 0 0; text-align: center;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em;
  color: var(--ink-secondary);
}

/* Hairline grid — cells share 1px lines via gap trick */
.hairgrid {
  display: grid;
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
}
.hairgrid > * { background: var(--bg); }

/* Services — 2×2: four merged cards, larger and airier (no empty gray cell) */
.services-grid { grid-template-columns: repeat(2, 1fr); }
.services-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
.service-card {
  padding: 32px 28px 40px;
  display: flex; flex-direction: column; gap: 12px;
  min-height: 180px;
  transition: background 200ms ease;
}
.service-card:hover { background: var(--bg-hover); }
.service-index { font-family: var(--mono); font-size: 12px; color: var(--ink-secondary); }
.service-card h3 { font-size: 19px; font-weight: 500; letter-spacing: -0.01em; line-height: 1.25; }
.service-card p { font-size: 15px; line-height: 1.5; color: var(--ink-secondary); margin: 0; }

/* Communication standards — how the work runs, day to day */
.standards-grid { grid-template-columns: repeat(2, 1fr); }
.standard-card {
  padding: 32px 28px 36px;
  display: flex; flex-direction: column; gap: 10px;
  transition: background 200ms ease;
}
.standard-card:hover { background: var(--bg-hover); }
.standard-card h3 { font-size: 19px; font-weight: 500; letter-spacing: -0.01em; line-height: 1.25; }
.standard-card p { font-size: 15px; line-height: 1.55; color: var(--ink-secondary); margin: 0; }

/* =========================================================================
   Digital services — bot cards with CSS-drawn chat demos
   ========================================================================= */
.digital-grid { grid-template-columns: repeat(2, 1fr); }
.bot-card {
  padding: 36px 32px 32px;
  display: flex; flex-direction: column; gap: 20px;
}
.bot-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
/* h2 since 2026-07-28 (heading-order); the size is the card's, not the
   document level's — h3 kept here so the rule still matches if a future
   page includes this partial under its own h2. */
.bot-head h2, .bot-head h3 { font-size: 21px; font-weight: 500; letter-spacing: -0.01em; }
/* A line chip, not a lime pill. Measured on /digital/ before the change:
   eight full-strength lime elements on one page, five of them .bot-tag —
   and three of those carried whole sentences ("Mini App · nothing to
   install"), which is not what a chip-scale accent is for (expert review
   2026-07-24, 2.3). Full-strength lime now stays with the marker, the 1-3px
   lines (progress hairline, nav underline, status dot) and the closing CTA.
   padding 3px/9px + 1px border = the pill's old box, so nothing reflows. */
.bot-tag {
  font-family: var(--mono); font-size: 10px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: var(--label-case, uppercase);
  border: 1px solid var(--border-interactive); color: var(--ink);
  padding: 3px 9px; border-radius: 999px;
}
.bot-features { list-style: none; margin: 0; padding: 0; }
.bot-features li {
  padding: 10px 0 10px 24px;
  border-top: 1px solid var(--hairline);
  font-size: 14px; line-height: 1.5; color: var(--ink-secondary);
  position: relative;
}
.bot-features li::before {
  content: '✓';
  position: absolute; left: 2px;
  color: var(--ink); font-size: 12px;
}

/* Chat demo — hairline-drawn dialog, same family as the hero ledger card */
.chat-demo {
  margin-top: auto;
  display: flex; flex-direction: column; gap: 8px;
  font-family: var(--mono); font-size: 12.5px;
}
.chat-msg { max-width: 85%; padding: 10px 14px; border-radius: 12px; line-height: 1.5; }
.chat-user {
  align-self: flex-end;
  background: var(--ink); color: var(--bg);
  border-bottom-right-radius: 4px;
}
.chat-bot {
  align-self: flex-start; width: 85%;
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  border-bottom-left-radius: 4px;
  display: flex; flex-direction: column; gap: 6px;
}
.chat-line { display: flex; justify-content: space-between; gap: 16px; font-variant-numeric: tabular-nums; }
.chat-line > span:first-child { color: var(--ink-secondary); text-transform: var(--label-case, uppercase); font-size: 11px; letter-spacing: 0.05em; padding-top: 2px; }
.chat-sub {
  font-size: 10.5px; letter-spacing: 0.04em;
  color: var(--ink-secondary);
  margin: -3px 0 2px;
}
.chat-greet {
  font-size: 11.5px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--hairline);
  margin-bottom: 2px;
}
.chat-total { border-top: 1px solid var(--hairline); padding-top: 6px; font-weight: 600; }
.chat-note { color: var(--ink-secondary); font-size: 11px; letter-spacing: 0.04em; }

/* Interactive bot demo — scenario chips + replayable dialog window.
   Beats are visible by default (no-JS, reduced-motion); .is-anim arms the
   hidden start state and JS replays the sequence. */
.chat-playground {
  margin-top: 56px;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
}
.playground-label { margin: 0; }
.chat-tabs { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; max-width: 640px; }
.chat-tab {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 9px 16px; border-radius: 999px; cursor: pointer;
  background: transparent; border: 1px solid var(--border-interactive); color: var(--ink);
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.03em;
  line-height: 1.2;
  transition: background 200ms ease, border-color 200ms ease, color 200ms ease;
}
.chat-tab:hover { background: var(--bg-hover); border-color: var(--ink-secondary); }
.chat-tab[aria-selected="true"] { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.tab-soon {
  font-size: 9px; font-weight: 600; letter-spacing: 0.06em; text-transform: var(--label-case, uppercase);
  background: var(--accent); color: var(--accent-ink);
  padding: 2px 7px; border-radius: 999px;
}
.chat-app--play { width: min(620px, 100%); }
.chat-app--play .chat-app-body { min-height: 330px; }
.chat-panel { display: flex; flex-direction: column; gap: 10px; }
/* display:flex above would defeat the hidden attribute — restore it */
.chat-panel[hidden], .chat-typing[hidden] { display: none; }
.chat-panel:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }
.demo-note { text-align: center; max-width: 460px; }
.is-anim [data-beat] { opacity: 0; transform: translateY(10px); }
.is-anim [data-beat].is-shown {
  opacity: 1; transform: none;
  transition: opacity 0.45s var(--ease-out), transform 0.45s var(--ease-out);
}
@media (max-width: 640px) {
  .chat-app--play .chat-app-body { min-height: 360px; }
}

/* Three cards since 2026-07-25 (the "data 24/7" and "fresh every morning"
   cards said the same thing) — the row divides evenly again instead of
   leaving a fourth empty cell in the hairgrid. */
.why-grid { grid-template-columns: repeat(3, 1fr); margin-top: 48px; }
.why-card { padding: 24px 22px 28px; display: flex; flex-direction: column; gap: 10px; }
.why-card p { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink-secondary); }
.why-card h3 { font-size: 17px; font-weight: 500; letter-spacing: -0.01em; line-height: 1.25; }

/* Guarantee callout — the trust anchor */
.guarantee {
  margin-top: 48px;
  border: 1px solid var(--ink);
  border-radius: 8px;
  padding: 28px 32px;
  display: flex; align-items: flex-start; gap: 20px;
}
.guarantee .bot-tag { flex: none; margin-top: 4px; }
.guarantee p {
  margin: 0;
  font-size: 18px; line-height: 1.5; letter-spacing: -0.01em;
  max-width: 62ch;
}
/* Data-safety callout — same family as the guarantee, quieter border */
.guarantee.data-safety { margin-top: 16px; border-color: var(--hairline); }
.guarantee.data-safety p { font-size: 15px; color: var(--ink-secondary); }

@media (max-width: 640px) {
  .guarantee { flex-direction: column; gap: 12px; padding: 22px 20px; }
}

.digital-cta { margin-top: 48px; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.digital-cta .form-note { max-width: 520px; }

@media (max-width: 1100px) {
  .why-grid { grid-template-columns: repeat(2, 1fr); }
  /* two bot cards side-by-side are too cramped for long hy feature lists */
  .digital-grid { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .why-grid { grid-template-columns: 1fr; }
}

/* =========================================================================
   Risk control — compact strip (the former fear→relief accordion, folded
   to three headline risks; details moved to the sales call, 2026-07)
   ========================================================================= */
.risk-strip {
  grid-template-columns: repeat(3, 1fr);
  list-style: none; margin: 0; padding: 0;
}
.risk-strip li {
  display: flex; flex-direction: column; gap: 10px;
  padding: 26px 30px;
  font-size: 17px; font-weight: 500; letter-spacing: -0.01em; line-height: 1.35;
}
.risk-label { font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: var(--label-case, uppercase); color: var(--ink-secondary); }
@media (max-width: 860px) {
  .risk-strip { grid-template-columns: 1fr; }
  .risk-strip li { padding: 20px; }
}

/* =========================================================================
   Pricing
   ========================================================================= */
.pricing-grid { grid-template-columns: repeat(3, 1fr); }
.pricing-card {
  position: relative;
  padding: 36px 32px 40px;
  display: flex; flex-direction: column; gap: 14px;
  transition: background 200ms ease;
}
.pricing-card:hover { background: var(--bg-hover); }
/* The chosen plan is marked in the system's own vocabulary — a 1px ink ring
   and the elevated paper — instead of the 1.5° sticker tilt the badge used to
   carry, the one gesture in a site built on straight rules (expert review
   2026-07-24, 2.8). box-shadow, not border: it draws over the hairgrid's own
   1px gap, so nothing in the row shifts. */
.pricing-card.popular {
  background: var(--bg-elevated);
  box-shadow: 0 0 0 1px var(--ink);
  z-index: 1;                      /* ring above the neighbours' hairlines */
}
.pricing-card.popular:hover { background: var(--bg-hover); }
.pricing-tag {
  position: absolute; top: 20px; right: 20px;
  background: var(--accent); color: var(--accent-ink);
  padding: 4px 10px; border-radius: 999px;
  font-family: var(--mono); font-size: 10px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: var(--label-case, uppercase);
}
.pricing-card h3 { font-size: 20px; font-weight: 500; letter-spacing: -0.01em; }
/* keep long hy plan names clear of the absolute-positioned tag */
.pricing-card.popular h3 { padding-right: 96px; }
.pricing-desc { font-size: 14px; color: var(--ink-secondary); margin: 0; }
.pricing-price { display: flex; align-items: baseline; gap: 8px; margin-top: 6px; }
.pricing-price .amount {
  font-family: var(--mono); font-size: 36px; font-weight: 500;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
.pricing-price .period { font-size: 14px; color: var(--ink-secondary); }
.pricing-features { list-style: none; margin: 6px 0 0; padding: 0; flex: 1; }
.pricing-features li {
  padding: 9px 0 9px 24px;
  border-top: 1px solid var(--hairline);
  font-size: 14px; line-height: 1.45; color: var(--ink-secondary);
  position: relative;
}
.pricing-features li::before {
  content: '✓';
  position: absolute; left: 2px;
  color: var(--ink); font-size: 12px;
}
/* Features 4+ live in a details (audit П7-lite): one seamless list on
   desktop (summary hidden, negative margin swallows the card's flex gap),
   an "All features" disclosure on phones — site.js closes it there. */
.pricing-features-more { margin-top: -14px; }
.pricing-features-more > summary { display: none; cursor: pointer; }
.pricing-features-more > summary::-webkit-details-marker { display: none; }
.pricing-features-more[open] .faq-chev { transform: rotate(180deg); }
.pricing-features-more .pricing-features { margin-top: 0; }
.pricing-card .btn { margin-top: 18px; }
/* The block's single CTA, now that the cards no longer each carry one. */
.pricing-cta { margin-top: 32px; display: flex; justify-content: center; }
@media (max-width: 640px) { .pricing-cta .btn { width: 100%; justify-content: center; } }

/* =========================================================================
   Inverse section — stats
   ========================================================================= */
.inverse {
  background-color: var(--bg-inverse);
  color: var(--ink-inverse);
}
.inverse-grid {
  display: grid; grid-template-columns: 1.2fr 1fr; gap: 64px; align-items: center;
  padding-block: 120px;
}
.inverse h2 {
  font-size: clamp(36px, 4.5vw, 56px);
  letter-spacing: -0.03em; line-height: 1.05;
  text-wrap: balance;
  overflow-wrap: break-word;
  /* Serif, like the other dark capitulum (.footer-cta): the page's two
     inverse sections should speak in one voice. Safe here in a way it is
     not in the hero — on dark, .inverse .gold carries the accent in colour,
     so making the heading serif costs no signal (2026-07-28, 5.3). */
  font-family: var(--serif); font-weight: 500; font-synthesis: none;
}
.stat-list { display: flex; flex-direction: column; gap: 40px; }
@media (min-width: 1100px) {
  /* Four stats in a column ran ~970px tall and left the bottom half of the
     left column empty. Two by two is the same content, ~300px shorter, and
     the section stops having a dead corner. */
  .stat-list { display: grid; grid-template-columns: 1fr 1fr; gap: 40px 48px; }
  .inverse-grid { align-items: start; }
}
.stat { border-top: 1px solid var(--hairline-inv); padding-top: 20px; }
.stat .value {
  font-family: var(--mono);
  font-size: 44px; font-weight: 500; letter-spacing: -0.02em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.stat .label { font-size: 15px; color: var(--ink-inverse-2); margin-top: 6px; }
/* The evidence line under the number. Quieter than the label on purpose —
   it is read second, by the visitor who wants to know why to believe the
   figure (expert review 2026-07-28, 2.2). */
.stat-note {
  font-size: 13px; line-height: 1.45; margin-top: 8px;
  color: var(--ink-inverse-2); opacity: 0.75; max-width: 34ch;
}

/* =========================================================================
   Process — editorial rows with oversized ghost numerals
   ========================================================================= */
.process-list { list-style: none; margin: 0; padding: 0; }
.process-step {
  display: grid; grid-template-columns: 110px 1fr 1.2fr; gap: 32px;
  align-items: start;
  padding: 36px 4px;
  border-top: 1px solid var(--hairline);
  transition: background 200ms ease;
}
.process-step:last-child { border-bottom: 1px solid var(--hairline); }
.process-step:hover { background: var(--bg-hover); }
.process-num {
  font-family: var(--mono);
  font-size: clamp(56px, 7vw, 96px);
  font-weight: 500;
  line-height: 0.9;
  color: var(--ink);
  opacity: 0.08;
  letter-spacing: -0.04em;
}
.process-step h3 { font-size: 22px; font-weight: 500; letter-spacing: -0.01em; padding-top: 6px; }
.process-step p { color: var(--ink-secondary); font-size: 15px; line-height: 1.55; margin: 0; padding-top: 9px; max-width: 60ch; }

/* =========================================================================
   Videos
   ========================================================================= */
.video-grid { grid-template-columns: repeat(2, 1fr); }
.video-card { padding: 20px 20px 24px; }
.video-frame {
  position: relative; aspect-ratio: 16 / 9;
  background: var(--bg-hover);
  border-radius: 8px; overflow: hidden;
}
.video-frame video, .video-frame iframe { width: 100%; height: 100%; border: 0; object-fit: cover; }

/* Click-to-load facade: no YouTube JS/errors until the visitor asks for it */
.video-facade {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; cursor: pointer;
  background: var(--bg-hover) center / cover no-repeat;
  display: grid; place-items: center;
  transition: filter 200ms ease;
}
.video-facade:hover { filter: brightness(0.96); }
.video-facade .play-pill {
  width: 60px; height: 60px; border-radius: 999px;
  background: var(--ink); color: var(--bg);
  display: grid; place-items: center;
  transition: transform 200ms ease;
}
.video-facade:hover .play-pill { transform: scale(1.06); }
.video-meta { padding-top: 16px; }
.video-meta h3 { font-size: 19px; font-weight: 500; letter-spacing: -0.01em; }
.video-meta p { color: var(--ink-secondary); font-size: 15px; margin: 4px 0 0; }

/* =========================================================================
   Gallery
   ========================================================================= */
.gallery-grid { columns: 3 260px; column-gap: 16px; }
.gallery-grid figure {
  margin: 0 0 16px; break-inside: avoid;
  border: 1px solid var(--hairline); border-radius: 8px; overflow: hidden;
  background: var(--bg-elevated);
}
.gallery-grid img { width: 100%; filter: saturate(0.92); transition: filter 200ms ease; }
.gallery-grid figure:hover img { filter: saturate(1); }
.gallery-grid figcaption {
  padding: 12px 14px;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em;
  color: var(--ink-secondary);
  border-top: 1px solid var(--hairline);
}

/* =========================================================================
   Testimonials
   ========================================================================= */
.testimonial-grid { grid-template-columns: repeat(3, 1fr); }
.testimonial {
  margin: 0; padding: 36px 32px;
  display: flex; flex-direction: column; gap: 24px;
}
.testimonial .quote {
  font-family: var(--serif); font-style: italic; font-synthesis: none;
  font-size: 23px; line-height: 1.4; letter-spacing: 0;
  margin: 0; flex: 1;
}
.testimonial .who .name { display: block; font-size: 14px; font-weight: 500; }
.testimonial .who .role { display: block; font-size: 13px; color: var(--ink-secondary); margin-top: 2px; }
.testimonial .stars {
  margin: 0; font-size: 15px; letter-spacing: 0.14em; color: var(--ink);
  line-height: 1;
}
.testimonial .who .source {
  display: inline-block; margin-top: 8px;
  font-size: 12px; color: var(--ink-secondary);
  border-bottom: 1px solid var(--hairline);
  transition: color 200ms ease, border-color 200ms ease;
}
.testimonial .who .source:hover { color: var(--ink); border-color: var(--ink); }

/* The first real testimonial arrives alone. A three-column grid would hang
   it in a third of the row next to two empty cells, which reads as "we have
   nothing" — the opposite of what one hard-won review should say. Alone, it
   takes the full width and the quote grows into a pull quote. Same for two
   (expert review 2026-07-28, 2.1). */
.testimonial-grid > :only-child {
  grid-column: 1 / -1;
  padding: 48px 40px;
  /* Not one wide column: a full-width card with text hugging the left edge
     leaves the right half dead, which is the very complaint the panel made
     about two other sections. Quote left, attribution parked at the bottom
     right, so the card is composed rather than merely stretched. */
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(180px, 0.7fr);
  grid-template-areas: "stars who" "quote who";
  gap: 20px 48px;
  align-content: start;
}
.testimonial-grid > :only-child .stars { grid-area: stars; }
.testimonial-grid > :only-child .quote { grid-area: quote; font-size: 30px; max-width: 32ch; }
.testimonial-grid > :only-child .who { grid-area: who; align-self: end; }
@media (max-width: 720px) {
  /* one column again — the split has no room, and the quote must lead */
  .testimonial-grid > :only-child {
    grid-template-columns: 1fr;
    grid-template-areas: "stars" "quote" "who";
    padding: 36px 28px;
  }
  .testimonial-grid > :only-child .quote { font-size: 23px; max-width: none; }
  .testimonial-grid > :only-child .who { align-self: start; }
}
.testimonial-grid:has(> :last-child:nth-child(2)) { grid-template-columns: repeat(2, 1fr); }

/* =========================================================================
   Team
   ========================================================================= */
.team-grid { grid-template-columns: repeat(4, 1fr); }
.team-card { display: flex; flex-direction: column; }
.team-photo { aspect-ratio: 3 / 4; background: var(--bg-hover); overflow: hidden; }
.team-photo img {
  width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(1); transition: filter 200ms ease;
}
.team-card:hover .team-photo img { filter: grayscale(0); }
.team-photo .ph {
  width: 100%; height: 100%; display: grid; place-items: center;
  color: var(--ink-secondary); font-size: 44px; font-weight: 500;
}
.team-info { padding: 20px 24px 28px; }
.team-info .name { font-size: 17px; font-weight: 500; letter-spacing: -0.01em; }
.team-info .role { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; text-transform: var(--label-case, uppercase); color: var(--ink-secondary); margin-top: 4px; }
.team-info .creds { font-size: 13px; color: var(--ink); margin-top: 8px; }
.team-info .bio { color: var(--ink-secondary); font-size: 14px; line-height: 1.5; margin: 10px 0 0; }

/* One person on a four-column grid is a quarter-width portrait beside three
   empty cells — it makes a small firm look emptier than saying nothing. The
   answer to "who keeps my books" is one face and one sentence, so alone the
   card turns landscape: portrait left, name and bio beside it
   (expert review 2026-07-28, 2.1). */
.team-grid > :only-child {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: minmax(200px, 280px) 1fr;
  align-items: center;
}
.team-grid > :only-child .team-photo { aspect-ratio: 4 / 5; }
.team-grid > :only-child .team-info { padding: 32px 40px; }
.team-grid > :only-child .team-info .name { font-size: 22px; }
.team-grid > :only-child .team-info .bio { max-width: 52ch; font-size: 15px; }
@media (max-width: 720px) {
  /* back to a plain stacked card — the landscape split has no room here */
  .team-grid > :only-child { grid-template-columns: 1fr; }
  .team-grid > :only-child .team-photo { aspect-ratio: 3 / 4; }
  .team-grid > :only-child .team-info { padding: 20px 24px 28px; }
}

/* =========================================================================
   Salary calculator page
   ========================================================================= */
.calc-page { padding-top: 160px; border-top: 0; }
.calc-shell {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
  background: var(--hairline); border: 1px solid var(--hairline);
  max-width: 880px;
}
.calc-shell > * { background: var(--bg-elevated); padding: 32px; }
.calc-mode { display: flex; gap: 8px; margin-bottom: 24px; }
.calc-mode button {
  padding: 9px 16px; border-radius: 999px; cursor: pointer;
  background: transparent; border: 1px solid var(--border-interactive); color: var(--ink);
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.03em; line-height: 1.2;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.calc-mode button[aria-pressed="true"] { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.calc-input label {
  display: block;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary); margin-bottom: 8px;
}
.calc-input input {
  width: 100%; padding: 14px 16px;
  font-family: var(--mono); font-size: 22px; font-variant-numeric: tabular-nums;
  color: var(--ink); background: var(--bg);
  border: 1px solid var(--border-interactive); border-radius: 8px;
  transition: border-color 150ms ease;
}
.calc-input input:focus { outline: none; border-color: var(--ink); }
/* First select on the site (the month picker on /timesheet/). Matches the
   text inputs exactly so the form reads as one control set; the native arrow
   is replaced because Safari and Chrome draw very different ones. */
.calc-input select {
  width: 100%; padding: 14px 40px 14px 16px;
  font-family: var(--mono); font-size: 22px;
  color: var(--ink); background: var(--bg);
  border: 1px solid var(--border-interactive); border-radius: 8px;
  transition: border-color 150ms ease;
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236E6C66' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center;
}
.calc-input select:focus { outline: none; border-color: var(--ink); }
/* Day / month / year in place of <input type="date">. The native control is
   drawn by the browser in the BROWSER's language — «ДД.ММ.ГГГГ» on an Armenian
   page in a Russian Chrome — and neither lang nor CSS reaches it. Three boxes
   on one row, sharing the border language of .calc-input so the trio still
   reads as a single field. Identical on /refund/, /penalty/ and /quote/. */
.calc-date { display: flex; gap: 8px; align-items: stretch; max-width: 340px; }
.calc-date-num,
.calc-date-sel {
  min-width: 0; padding: 13px 12px;
  color: var(--ink); background: var(--bg);
  border: 1px solid var(--border-interactive); border-radius: 8px;
  transition: border-color 150ms ease;
}
.calc-date-num {
  font-family: var(--mono); font-size: 20px; font-variant-numeric: tabular-nums;
  text-align: center;
}
.calc-date-num--d { flex: 0 0 58px; }
.calc-date-num--y { flex: 0 0 86px; }
/* The month is a word, not a figure — it takes the remaining room and a
   reading size. Armenian «Սեպտեմբեր» is the longest of the three languages. */
.calc-date-sel {
  flex: 1 1 auto;
  font-family: var(--sans); font-size: 15px;
  padding-right: 32px;
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236E6C66' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center;
}
.calc-date-num:focus,
.calc-date-sel:focus { outline: none; border-color: var(--ink); }
.calc-date-num::placeholder { color: var(--ink-secondary); opacity: 0.45; }
.calc-date-num[aria-invalid="true"],
.calc-date-sel[aria-invalid="true"] { border-color: var(--danger-border); }
@media (max-width: 640px) {
  /* Thumbs, not cursors: the row keeps all three on one line but gives the
     month whatever is left after two fixed boxes. */
  .calc-date { max-width: none; gap: 6px; }
  .calc-date-num--d { flex: 0 0 54px; }
  .calc-date-num--y { flex: 0 0 78px; }
}
.calc-note { color: var(--ink-secondary); font-size: 13px; margin-top: 16px; max-width: 40ch; }
/* In-text links inside a note: the global `a` is bare, so give them the
   site's quiet underline (hairline at rest, ink on hover) — same device as
   the hero's secondary action. */
.calc-note a {
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: var(--hairline);
  transition: text-decoration-color 150ms ease, color 150ms ease;
}
.calc-note a:hover { color: var(--ink); text-decoration-color: var(--ink); }
/* /regime/ only: the articles that close a regime. A list, not prose — each
   line is a separate statutory ground and reads as one. */
.regime-reasons {
  margin: 6px 0 0; padding-left: 18px;
  color: var(--ink-secondary); font-size: 13px; line-height: 1.5;
  max-width: 46ch;
}
.regime-reasons li { margin-top: 4px; }
.calc-check {
  display: flex; align-items: flex-start; gap: 10px;
  margin-top: 14px; cursor: pointer;
  font-size: 14px; color: var(--ink-secondary); line-height: 1.4;
}
.calc-check input { margin-top: 3px; accent-color: var(--ink); width: 16px; height: 16px; flex: none; }
.calc-check:hover { color: var(--ink); }
/* An option that carries a statute reference: the sentence is what a person
   chooses by, the article is what they check against their termination order.
   Inside the sentence it cost three or four lines of Armenian per option and
   made the group the heaviest object on the page. */
.calc-check-body { display: block; min-width: 0; }
.calc-check-ref {
  display: block; margin-top: 3px;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums; color: var(--ink-secondary);
}
/* Until now the only sign of the chosen option was a 16px circle — the label
   read identically whether picked or not. Progressive enhancement: without
   :has() the native radio still carries the state on its own. */
.calc-check:has(input:checked) { color: var(--ink); font-weight: 500; }
.calc-check:has(input:checked) .calc-check-ref { font-weight: 400; }
/* A line of guidance under a legend, tighter than .calc-note. */
.calc-hint { margin: 2px 0 10px; font-size: 12.5px; line-height: 1.45; color: var(--ink-secondary); max-width: 44ch; }
/* A field that follows from the answer above it. */
.calc-part + .calc-input { margin-top: 20px; }
/* The settings whose default fits almost everyone, folded behind a summary
   that states them. Same disclosure mechanics as .faq-item, quieter. */
.calc-advanced { margin-top: 24px; border-top: 1px solid var(--hairline); }
.calc-advanced > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 0; min-height: 44px;
  cursor: pointer; list-style: none;
  transition: color 150ms ease;
}
.calc-advanced > summary::-webkit-details-marker { display: none; }
.calc-advanced > summary:hover .calc-advanced-state { color: #000; }
.calc-advanced[open] .faq-chev { transform: rotate(180deg); }
.calc-advanced-text { min-width: 0; }
.calc-advanced-cap {
  display: block;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
}
.calc-advanced-state {
  display: block; margin-top: 3px;
  font-size: 13px; line-height: 1.45; color: var(--ink);
  transition: color 150ms ease;
}
.calc-advanced-body { padding-bottom: 4px; }
.calc-advanced-body > .calc-part:first-child { margin-top: 0; }
.calc-input { margin-top: 8px; }
.calc-part { margin-top: 20px; }
.calc-part .intent-legend { margin-bottom: 2px; }
.calc-part .calc-check { margin-top: 10px; }
.calc-results { display: flex; flex-direction: column; gap: 0; }
.calc-row {
  display: flex; justify-content: space-between; gap: 16px; align-items: baseline;
  padding: 12px 0; border-top: 1px solid var(--hairline);
  font-size: 15px;
}
/* An author `display` always beats the UA sheet's [hidden] { display: none },
   so a row the JS hides with .hidden = true kept rendering. It bit /penalty/
   in production: the late-filing fine row showed "0 ֏" with the checkbox
   unchecked (found 2026-08-01 while building /dividend/, which hides rows the
   same way). The sibling notes were never affected — a <p> is display:block,
   so [hidden] wins there. */
.calc-row[hidden] { display: none; }
.calc-row:first-child,
/* ...and when the leading rows are hidden (on /dividend/ the profit and
   profit-tax rows go when you start from an already-taxed amount), the first
   VISIBLE row must lose the rule too — otherwise a stray hairline floats at
   the top of the panel. Anchored on :first-child so a row hidden in the
   MIDDLE of the list still keeps its separator. */
.calc-row[hidden]:first-child + .calc-row,
.calc-row[hidden]:first-child + .calc-row[hidden] + .calc-row { border-top: 0; padding-top: 0; }
/* Same rule as .report-row: the label shrinks, the number does not (audit
   2026-07-25 — the total pushed 2px past the card's content edge at 375px). */
.calc-row .k { color: var(--ink-secondary); min-width: 0; overflow-wrap: anywhere; }
.calc-row .v { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* /benefits/ answers its top panel in sentences, not figures. The nowrap
   above exists so a sum never breaks across lines; applied to a 60-word
   explanation it makes the row an ~800px unbreakable box, which forces the
   grid track open and squeezes the form column to a third of the plate
   (measured 296px of 880 — this predates the 1.1/0.9 split). Those values
   wrap; the caps table further down the page keeps its numbers intact. */
.calc-results--prose .calc-row .v { white-space: normal; }
.calc-row--total { font-weight: 600; font-size: 17px; }
.calc-row--total .v { font-size: 20px; }

/* ---- Result in three tiers ------------------------------------------------
   The answer used to be the ninth row of a nine-row table: 20px against 15px,
   a ratio of 1.33:1. That is not a hierarchy — the eye has nothing to land on,
   which is exactly what "непонятно визуально" described (audit 2026-08-30).
   Now: the answer, then the two sums it is made of, then the arithmetic under
   a ledger caption. No new visual vocabulary — .calc-group-cap is
   .report-section, and .calc-answer .v is .cal-stat .v. */
.calc-group-cap {
  font-family: var(--mono);
  font-size: 11px; letter-spacing: 0.1em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary);
  margin: 0 0 14px; padding-bottom: 8px;
  border-bottom: 1px solid var(--hairline);
}
/* Tier 1. The 2px accent rule replaces the marker wash that used to sit under
   the number: --accent is specified for chip scale and 1-3px lines, and
   --accent-soft on white measured ~1.2:1 — invisible on a phone screenshot,
   and stripped in print anyway. */
.calc-answer { border-bottom: 2px solid var(--accent); }
.calc-answer .k {
  display: block; margin-bottom: 10px;
  font-family: var(--mono);
  font-size: 11px; letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary);
}
.calc-answer .v {
  display: block;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: clamp(34px, 4.4vw, 46px); line-height: 1.02; letter-spacing: -0.02em;
  white-space: nowrap;
}
/* Reuses @keyframes estTick, written for the /quote/ estimator and until now
   never applied to a calculator. */
.calc-answer .v.is-updated,
.calc-sticky .v.is-updated { animation: estTick 300ms var(--ease-out); }

/* Tier 2 — the two sums the answer is made of. Their labels are ink, not
   --ink-secondary: these are answers too, not annotations. */
.calc-row--lead { font-size: 17px; padding: 14px 0; }
.calc-row--lead:first-of-type { border-top: 0; padding-top: 0; }
.calc-row--lead .k { color: var(--ink); }
.calc-row--lead .v { font-size: 18px; }

/* Tier 3 — how the figure was reached. */
.calc-breakdown { margin-top: 28px; }
.calc-breakdown .calc-row { font-size: 13.5px; padding: 8px 0; }
.calc-breakdown .calc-row:first-of-type { border-top: 0; padding-top: 0; }

/* Four notes used to stack directly under the total, occupying more area than
   the result itself. One block, set apart by a rule. */
.calc-footnotes { margin-top: 26px; padding-top: 14px; border-top: 1px solid var(--hairline); }
.calc-footnotes .calc-note { margin-top: 8px; font-size: 12.5px; max-width: 46ch; }
.calc-footnotes .calc-note:first-of-type { margin-top: 0; }

/* Desktop: the answer heads the right column, level with the first input;
   the rest of the panel sits under it. The form spans both rows. */
@media (min-width: 861px) {
  /* 1.1 / 0.9, not 50/50: the left column wraps sentences, the right one
     holds numbers that carry white-space: nowrap. Measured at 1440px, the
     longest Armenian option drops from four rendered lines to three once the
     form column clears ~465px of content width — 375px today. The plate keeps
     its left edge on the page's margin rather than centring: the H1 and the
     prose below hang off the same line, and a centred block would break it. */
  .calc-shell { grid-template-columns: 1.1fr 0.9fr; max-width: 1040px; }
  .calc-shell > * { padding: 36px 40px; }
  /* A number field does not have to be as wide as a paragraph — the longest
     value here is nine characters at 22px. Selects are left alone: the zone
     names on /refund/ need the whole column. */
  .calc-shell .calc-input input { max-width: 340px; }

  /* Row 1 hugs the answer. Without this the form, spanning both rows, hands
     its surplus height to row 1 as well and the number floats in the middle
     of an over-tall block. Scoped to the shells that HAVE an answer: on the
     other calculators row 1 would collapse to 0 and leave a stray hairline
     across the top of the right column. */
  .calc-shell--answer { grid-template-rows: min-content 1fr; }
  .calc-shell--answer > .calc-form { grid-column: 1; grid-row: 1 / span 2; }
  .calc-shell--answer > .calc-answer { grid-column: 2; grid-row: 1; }
  .calc-shell--answer > .calc-results { grid-column: 2; grid-row: 2; }
}

/* The phone-only answer bar. position:fixed, NOT sticky: body carries
   overflow-x:hidden, which makes it a scroll container and silently breaks
   position:sticky in Chrome and Safari. Same device as .cta-sticky. */
.calc-sticky { display: none; }
@media (max-width: 860px) {
  .js .calc-sticky:not([hidden]) {
    display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    padding: 10px 20px calc(10px + env(safe-area-inset-bottom));
    background: var(--bg-elevated);
    border-top: 2px solid var(--accent);
  }
  .calc-sticky .k {
    font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
    text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
    min-width: 0; overflow-wrap: anywhere;
  }
  .calc-sticky .v {
    font-family: var(--mono); font-variant-numeric: tabular-nums;
    font-size: 20px; letter-spacing: -0.01em; white-space: nowrap;
  }
}
.calc-seo { max-width: 720px; margin-top: 72px; }
.calc-seo h2 { font-size: clamp(26px, 3vw, 34px); letter-spacing: -0.02em; line-height: 1.15; margin-bottom: 16px; }
.calc-seo p { color: var(--ink-secondary); font-size: 16px; line-height: 1.65; margin: 0 0 18px; }
.calc-cta { margin-top: 48px; display: flex; flex-wrap: wrap; align-items: center; gap: 20px; }
@media (max-width: 860px) {
  .calc-page { padding-top: 120px; }
  .calc-shell { grid-template-columns: 1fr; }
  .calc-shell > * { padding: 24px 20px; }
  /* One column: the answer goes first. The page ships with real
     defaults, so it is a worked example on arrival, not an empty
     frame — and it is no longer ~1900px below the field being
     typed into. */
  .calc-shell > .calc-answer { order: -1; }
}
@media (max-width: 640px) {
  /* The H1 was 36px against a 20px total: the name of the tool beat
     the tool's output, and the intro pushed the form off the first
     screen. On a calculator the display level belongs to the number. */
  .calc-page { padding-top: 96px; }
  .calc-page .section-head { margin-bottom: 24px; }
  .calc-page .section-head h1 { font-size: clamp(26px, 7.2vw, 33px); line-height: 1.12; }
  .calc-page .section-head p { font-size: 15px; }
  .calc-answer .v { font-size: clamp(30px, 8vw, 36px); }
}

/* =========================================================================
   Quote quiz page
   ========================================================================= */
.quote-form { max-width: 720px; }
.quote-step { border: 0; padding: 0; margin: 0; min-width: 0; }
.quote-steps { display: flex; gap: 24px; margin-bottom: 36px; }
/* Step labels are informative text ("2 · Your contacts"), not decoration, so
   they owe 4.5:1. opacity 0.4 on --ink gave ~2.5:1 (axe color-contrast on
   /quote/, expert review 2026-07-28, 1.6). Dimming by colour instead keeps
   the same visual step-down at 4.9:1. */
.quote-steps span { color: var(--ink-secondary); transition: color 200ms ease; }
.quote-steps span.on { color: var(--ink); }
.quote-q { margin-bottom: 30px; }
.quote-q .intent-legend { margin-bottom: 10px; }
.quote-q.has-error .intent-legend { color: var(--danger); }
/* The colour is the SECOND signal here — the text in .field-error, which
   estimator.js injects, is the first. It used to be the only one, in a
   red of 1.77:1 (expert review, C2 + 2.6). */
.quote-q.has-error .intent-chip > span { border-color: var(--danger-border); }
/* JS-injected group error sits directly under the legend, above the chips. */
.quote-q .field-error { margin: 0 0 10px; }
.quote-q .field-error[hidden] { display: none; }
.quote-q.has-legal-error .intent-legend,
.field.has-legal-error label { color: var(--danger); }
.quote-q.has-legal-error .intent-chip input[value="micro"] + span,
.field.has-legal-error input { border-color: var(--danger-border); }
.tax-legal-warning {
  max-width: 620px; margin: -12px 0 30px;
  border: 1px solid var(--danger-border); border-left: 4px solid var(--danger);
  border-radius: 8px; padding: 15px 17px;
  background: var(--danger-bg); color: var(--danger);
}
.tax-legal-warning[hidden] { display: none; }
.tax-legal-warning p { margin: 0; font-size: 14px; line-height: 1.55; }
.tax-legal-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  margin-top: 12px;
}
.tax-legal-actions .btn-small { padding: 8px 12px; min-height: 0; font-size: 13px; }
.tax-legal-actions a {
  color: inherit; font-size: 12px; text-decoration: underline;
  text-underline-offset: 2px;
}
.quote-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; max-width: 560px; }
.quote-nav { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 12px; }
.quote-form .field { max-width: 560px; }
.quote-estimate {
  max-width: 620px; margin-top: 8px;
  border: 1px solid var(--ink); border-radius: 8px;
  padding: 28px 32px;
  display: flex; gap: 20px; align-items: flex-start;
}
.quote-estimate .bot-tag { flex: none; margin-top: 4px; }
/* min-width: 0 — a flex item refuses to shrink below its min-content width by
   default, so one long unbreakable line inside the body (a price sentence, a
   16-glyph Armenian word) used to widen the whole card. This is the structural
   half of the 2026-07-25 phone fix; the scoped nowrap above is the other. */
.quote-estimate-body { min-width: 0; }
.quote-estimate-body h2 { font-size: 22px; letter-spacing: -0.01em; }
.quote-estimate-body .pricing-price { margin-top: 10px; }
@media (max-width: 640px) {
  .quote-grid2 { grid-template-columns: 1fr; }
  .quote-estimate { flex-direction: column; gap: 12px; padding: 22px 20px; }
}

/* --- Calculators hub ----------------------------------------------------- */
.calc-breadcrumb { margin-bottom: 20px; }
.calc-breadcrumb a {
  font-size: 14px; color: var(--ink-secondary);
  transition: color 200ms ease;
}
.calc-breadcrumb a:hover { color: var(--ink); }

/* --- Calculators hub: grouped tool cards ---------------------------------
   Before this, the tools read at one weight: a 26px line icon lost against a
   bordered pill that three of five cards repeated verbatim ("2026 rates"),
   plus an "Open →" line identical on every card, and nothing saying what a
   tool hands back. Now: named groups (one grid row each), a 48px icon tile,
   and a result rail at the foot — the same label/value-over-hairline device
   .calc-row uses, so the hub rhymes with the pages it links to.
   auto-fit/minmax is gone deliberately: at 1280 it resolved to FOUR columns,
   so five tools rendered 4+1 and six would render 4+2. Fixed counts keep
   every breakpoint a complete rectangle. (Owner decision 2026-08-01.) */
.tools-section + .tools-section { margin-top: 44px; }
.tools-group {
  font-family: var(--mono); font-size: 12px; font-weight: 500;
  letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary);
  margin: 0 0 14px; padding-bottom: 10px;
  border-bottom: 1px solid var(--hairline);
}

.tools-grid {
  margin-top: 8px;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;
}
.tool-card {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 12px; position: relative;
  padding: 24px 24px 22px;
  border: 1px solid var(--hairline); border-radius: 10px;
  background: var(--bg);
  transition: transform 250ms ease, border-color 250ms ease, background 250ms ease;
}
.tool-card:hover { transform: translateY(-3px); border-color: var(--ink); background: var(--bg-hover); }
.tool-card:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* Head row: the tile anchors the card's left edge and the badge sits opposite
   it, instead of a pill floating over ~180px of dead space. */
.tool-head {
  width: 100%; display: flex; align-items: center;
  justify-content: space-between; gap: 12px;
}
.tool-tile {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; border-radius: 10px;
  background: var(--bg-hover); border: 1px solid var(--hairline); color: var(--ink);
  transition: background 250ms ease, border-color 250ms ease;
}
/* The only lime on this page, and it is transient — hover/focus, chip scale.
   That is what --accent is rationed for; nothing is lime at rest. */
.tool-card:hover .tool-tile,
.tool-card:focus-visible .tool-tile { background: var(--accent); border-color: var(--accent); }

.tool-card h3 { font-size: 20px; letter-spacing: -0.01em; margin: 0; }
.tool-card p { color: var(--ink-secondary); font-size: 15px; line-height: 1.55; margin: 0; }

/* "What you get back". margin-top:auto pins it to the foot, so the rails line
   up across a row whatever the blurb length — no min-height needed. */
.tool-out {
  margin-top: auto; width: 100%;
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding-top: 12px; border-top: 1px solid var(--hairline);
  font-family: var(--mono); font-size: 13px; font-weight: 500; color: var(--ink);
}
.tool-out .arrow { transition: transform 250ms ease; }
.tool-card:hover .tool-out .arrow { transform: translateX(3px); }

/* No longer a pill: the badge survives only on a card whose tool has a
   verified article of law behind it, so it no longer needs to shout. */
.tool-badge {
  font-family: var(--mono); font-size: 11.5px;
  letter-spacing: 0.02em; color: var(--ink-secondary);
}

/* Tablet + phone: the card turns on its side — tile and title share the top
   line, blurb sits in the title's column, rail spans the card. */
@media (max-width: 1023px) {
  .tools-grid { grid-template-columns: repeat(2, 1fr); gap: 14px; }
  .tool-card {
    display: grid; grid-template-columns: 40px 1fr;
    column-gap: 14px; row-gap: 8px; align-items: start;
    padding: 18px 18px 16px;
  }
  .tool-head    { display: contents; }
  .tool-tile    { width: 40px; height: 40px; border-radius: 9px; grid-column: 1; grid-row: 1; }
  .tool-tile svg { width: 20px; height: 20px; }
  .tool-badge   { display: none; }
  .tool-card h3 { grid-column: 2; grid-row: 1; font-size: 17px; align-self: center; }
  .tool-card p  { grid-column: 2; font-size: 14px; line-height: 1.5; }
  .tool-out     { grid-column: 1 / -1; margin-top: 4px; padding-top: 12px; }
}
@media (max-width: 640px) { .tools-grid { grid-template-columns: 1fr; gap: 12px; } }

/* --- "Other calculators" strip under each calculator page ----------------
   Wayfinding, not a catalogue: compact icon+title pills (a full-mesh sidebar
   was rejected — SITE-STRUCTURE-DECISIONS.md, 2026-07-31). Sits below
   .calc-cta / above .calc-seo, borrows the hub's tile idiom at 32px so the
   two read as one family, and prints as nothing. Pills size to content and
   wrap — no grid, so 4 links and 5 links both land as a complete strip. */
.calc-related { margin-top: 56px; }
.calc-related-cap {
  font-family: var(--mono); font-size: 12px; font-weight: 500;
  letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary);
  margin: 0 0 14px; padding-bottom: 10px;
  border-bottom: 1px solid var(--hairline);
}
.calc-related-row { display: flex; flex-wrap: wrap; gap: 10px; }
.calc-related-card {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 8px 16px 8px 8px;
  border: 1px solid var(--hairline); border-radius: 10px;
  background: var(--bg);
  font-size: 15px; color: var(--ink); text-decoration: none;
  transition: transform 250ms ease, border-color 250ms ease, background 250ms ease;
}
.calc-related-card:hover { transform: translateY(-2px); border-color: var(--ink); background: var(--bg-hover); }
.calc-related-card:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.calc-related-tile {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 8px;
  background: var(--bg-hover); border: 1px solid var(--hairline); color: var(--ink);
  transition: background 250ms ease, border-color 250ms ease;
}
.calc-related-card:hover .calc-related-tile { background: var(--accent); border-color: var(--accent); }
/* The hub link carries no tile — the arrow is its mark, and it nudges on
   hover like every other arrow on the site. */
.calc-related-all { padding: 8px 16px; font-family: var(--mono); font-size: 13px; font-weight: 500; }
.calc-related-all .arrow { transition: transform 250ms ease; }
.calc-related-all:hover .arrow { transform: translateX(3px); }
/* Share the calculation (plan K11). Sits between the result and the CTA, and
   is quieter than both: it is a courtesy, not an offer. Hidden until site.js
   reveals it — the buttons do nothing without JS. */
.calc-share {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px;
  margin: 24px 0 0;
}
.calc-share-cap {
  font-family: var(--mono); font-size: 12px; font-weight: 500;
  letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary); margin-right: 4px;
}
.calc-share-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px; min-height: 44px;
  border: 1px solid var(--hairline); border-radius: 10px;
  background: var(--bg); color: var(--ink);
  font-size: 14px; font-family: inherit; text-decoration: none;
  cursor: pointer;
  transition: border-color 200ms ease, background 200ms ease, transform 200ms ease;
}
.calc-share-btn:hover { border-color: var(--ink); background: var(--bg-hover); transform: translateY(-1px); }
.calc-share-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.calc-share-btn svg { flex: none; color: var(--ink-secondary); }
.calc-share-btn:hover svg { color: var(--ink); }
.calc-share-btn.is-copied { border-color: var(--accent); }
@media (max-width: 640px) {
  /* The caption becomes its own line rather than squeezing the buttons. */
  .calc-share-cap { flex: 0 0 100%; }
}

/* The service line under the strip (plan K4). A sentence, not a card: it is a
   different kind of offer, and a fifth card would read as another calculator. */
.calc-related-service {
  margin: 16px 0 0; font-size: 15px; line-height: 1.55;
  color: var(--ink-secondary);
}
.calc-related-service a {
  color: var(--ink); border-bottom: 1px solid var(--hairline);
  transition: border-color 200ms ease;
}
.calc-related-service a:hover { border-color: var(--ink); text-decoration: none; }
.calc-related-service .arrow { transition: transform 250ms ease; display: inline-block; }
.calc-related-service a:hover .arrow { transform: translateX(3px); }
/* Same strip, mirrored onto the service pages. */
.service-tools { margin-top: 64px; }

/* Tax calendar (plan K17), rebuilt on the owner's review 2026-09-02.
   No month grid: fourteen dates over 365 squares is 3.8% signal, and the one
   fact the data is mostly made of — "the 20th, every month" — is invisible in
   a paged month view because two months never show at once. The shapes here
   are a year rail, a schedule and a set of cards. */
.tc-sibling { margin-top: 10px; font-size: 14px; color: var(--ink-secondary); }
.tc-sibling a { color: var(--ink); border-bottom: 1px solid var(--hairline); }
.tc-banner { border-left: 3px solid var(--accent); padding-left: 12px; }

/* The next deadline, answered before any interaction. */
.tc-next {
  display: grid; grid-template-columns: auto 1fr; gap: 28px; align-items: center;
  margin-top: 32px; padding: 24px 0; border-block: 1px solid var(--hairline);
}
.tc-next-date { display: grid; justify-items: start; line-height: 1; }
/* "by" sits above the number and cannot be read apart from it: the date is
   the LAST day, not the day you file. */
.tc-next-by {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
  margin-bottom: 6px;
}
.tc-next-num {
  font-size: clamp(56px, 12vw, 112px); font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.tc-next-month { font-size: 20px; margin-top: 2px; }
.tc-next-dow {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  color: var(--ink-secondary); margin-top: 6px;
}
.tc-next-body { min-width: 0; }
.tc-next-left { margin: 0; font-size: 17px; }
.tc-next-moved { margin: 6px 0 0; font-size: 14px; color: var(--ink-secondary); }
/* A date is a point; a bar that is filling is a window closing. */
.tc-bar {
  height: 4px; border-radius: 2px; background: var(--bg-hover);
  border: 1px solid var(--hairline); margin: 14px 0 12px; overflow: hidden;
}
.tc-bar-fill { display: block; height: 100%; background: var(--ink); }
.tc-next-what { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.tc-next-what a {
  font-size: 15px; color: var(--ink); border-bottom: 1px solid var(--hairline);
}
.tc-next-what a:hover { border-color: var(--ink); text-decoration: none; }

/* The year in twelve columns: one axis, not twelve boxes (rebuilt after the
   owner's review, 2026-09-04). Every month's LAST deadline sits on a shared
   baseline; a second deadline, or the statutory day a moved one came from,
   rises above it. Every day is a real anchor link — nothing here loads, it
   scrolls, which is why the whole page stays in the HTML. */
.tc-rail {
  display: grid; grid-template-columns: repeat(12, 1fr);
  margin-top: 28px;
}
.tc-rail-cell {
  display: flex; flex-direction: column; align-items: center;
  min-width: 0; padding-top: 4px;
}
/* margin-top:auto is the whole fix for the ellipse. The grid still stretches
   every cell to the tallest, but the stretch now lands on empty space above
   the stack instead of on the pill — which is what turned ten of twelve pills
   into 34x54 ovals while February's and November's, having a sibling to share
   the row with, stayed circles. */
.tc-rail-stack {
  margin-top: auto; padding-bottom: 12px;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.tc-rail-slot { display: flex; flex-direction: column; align-items: center; gap: 1px; }
/* The moved-from day, struck. NOT a symbol: U+21B7 is in none of Instrument
   Sans, Manrope or Noto Sans Armenian — measured at an identical width in all
   three AND in the generic fallback, which is the signature of a glyph nobody
   draws — so it came from the OS at a foreign weight and shoved the digit
   off-centre. A numeral plus a CSS rule cannot fall through to another font,
   and it needs no legend to work: 20 crossed out over a live 22 says it. */
.tc-rail-was {
  font-family: var(--mono); font-size: 11px; line-height: 1.2;
  color: var(--ink-secondary); font-variant-numeric: tabular-nums;
  text-decoration: line-through; text-decoration-thickness: 1px;
}
/* Fixed 44, not min-*: a min-height inside a stretched item still grows, and
   44 is the touch target the 34px-wide pill was failing. */
.tc-rail-day {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 999px;
  font-size: 16px; line-height: 1; font-variant-numeric: tabular-nums;
  color: var(--ink); background: var(--bg-hover); text-decoration: none;
  /* The fill is 1.07:1 from the page, so the border IS the control's only
     boundary and 1.4.11 asks 3:1 of it. --hairline gave 1.21:1. */
  border: 1px solid var(--border-interactive);
  transition: background 250ms ease, border-color 250ms ease;
}
.tc-rail-day:hover { background: var(--accent); border-color: var(--accent); }
.tc-rail-day:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
/* The deadline the top of the page is already counting down to. Accent plus
   an ink ring, so it is never colour alone. */
.tc-rail-day.is-next {
  background: var(--accent); border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink); font-weight: 500;
}
/* Filtered out: the row this points at is hidden, so the link would scroll
   nowhere. Kept in the DOM and in the layout — the year must not reflow when
   a regime is picked — but visibly and functionally out. */
.tc-rail-day.is-off { opacity: 0.3; pointer-events: none; }
.tc-rail-day.is-off:hover { background: var(--bg-hover); border-color: var(--border-interactive); }
/* A month with nothing due: a drawn gap on the line, not an empty box. */
.tc-rail-none {
  width: 44px; height: 44px;
  background: linear-gradient(var(--hairline), var(--hairline)) center / 14px 1px no-repeat;
}
/* Twelve adjacent top borders with no column gap make one continuous axis —
   which is what turns twelve cards into a chart. */
.tc-rail-month {
  display: block; width: 100%; text-align: center;
  padding: 8px 2px 0; border-top: 1px solid var(--hairline);
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
  white-space: nowrap; overflow: hidden;
}
.tc-rail-legend { margin: 12px 0 0; font-size: 13px; line-height: 1.5; color: var(--ink-secondary); }
.tc-rail-legend-pair { margin-right: 4px; color: var(--ink); font-variant-numeric: tabular-nums; }
.tc-rail-legend-pair s { color: var(--ink-secondary); text-decoration-thickness: 1px; }

/* Filter. Radios, because a business is on exactly one regime. */
.tc-filter { margin: 32px 0 8px; display: grid; gap: 14px; }
.tc-filter fieldset { border: 0; padding: 0; margin: 0; }
.tc-filter legend {
  font-family: var(--mono); font-size: 12px; font-weight: 500;
  letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary); padding: 0;
}
.tc-filter-hint { margin: 6px 0 12px; font-size: 13px; color: var(--ink-secondary); }
.tc-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tc-chip {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px;
  padding: 8px 14px; border: 1px solid var(--hairline); border-radius: 999px;
  background: var(--bg); font-size: 14px; cursor: pointer;
  transition: border-color 250ms ease, background 250ms ease;
}
.tc-chip:hover { border-color: var(--ink); background: var(--bg-hover); }
.tc-chip:has(input:checked) { border-color: var(--ink); background: var(--bg-hover); }
.tc-chip input { accent-color: var(--ink); margin: 0; }
.tc-chip:focus-within { outline: 2px solid var(--ink); outline-offset: 3px; }
.tc-reset {
  justify-self: start; background: none; border: 0; padding: 0;
  font-family: var(--mono); font-size: 12px; color: var(--ink-secondary);
  border-bottom: 1px solid var(--hairline); cursor: pointer;
}
.tc-reset:hover { color: var(--ink); border-color: var(--ink); }

/* The schedule. One line per date; the text of each duty lives once, below. */
.tc-list { list-style: none; margin: 24px 0 0; padding: 0; }
.tc-day {
  display: grid; grid-template-columns: 116px 1fr; gap: 24px;
  padding: 18px 0; border-top: 1px solid var(--hairline);
  scroll-margin-top: 96px;
}
.tc-day[hidden] { display: none; }
.tc-day:target { background: var(--bg-hover); }
.tc-date { margin: 0; display: flex; flex-direction: column; line-height: 1.2; }
.tc-date-num { font-size: 28px; font-variant-numeric: tabular-nums; }
.tc-date-month { font-size: 14px; color: var(--ink-secondary); }
.tc-date-dow {
  margin-top: 4px; font-family: var(--mono); font-size: 11px;
  letter-spacing: 0.06em; color: var(--ink-secondary);
}
.tc-date-moved {
  margin-top: 6px; font-family: var(--mono); font-size: 11px;
  line-height: 1.4; color: var(--ink-secondary);
}
.tc-duties { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; align-content: center; }
.tc-duty[hidden] { display: none; }
.tc-duty a {
  font-size: 16px; color: var(--ink); border-bottom: 1px solid var(--hairline);
}
.tc-duty a:hover { border-color: var(--ink); text-decoration: none; }
.tc-empty { margin-top: 20px; font-size: 15px; color: var(--ink-secondary); }

/* What each duty is — written once, not once per month. */
.tc-cards { margin-top: 56px; display: grid; gap: 18px; }
.tc-cards > h2 { margin: 0 0 4px; }
.tc-card {
  padding: 18px 20px; border: 1px solid var(--hairline); border-radius: 10px;
  background: var(--bg); scroll-margin-top: 96px;
}
.tc-card[hidden] { display: none; }
.tc-card:target { border-color: var(--ink); }
.tc-card h3 { margin: 0 0 4px; font-size: 18px; }
.tc-card-when {
  margin: 0 0 10px; font-family: var(--mono); font-size: 12px;
  letter-spacing: 0.02em; color: var(--ink-secondary);
}
.tc-card p { margin: 0 0 6px; font-size: 15px; line-height: 1.55; }
.tc-articles {
  font-family: var(--mono); font-size: 12px; color: var(--ink-secondary);
  letter-spacing: 0.02em;
}
.tc-late { margin: 6px 0 0; font-size: 15px; color: var(--ink-secondary); }
.tc-late a { color: var(--ink); border-bottom: 1px solid var(--hairline); }
.tc-late a:hover { border-color: var(--ink); text-decoration: none; }
.tc-late .arrow { transition: transform 250ms ease; display: inline-block; }
.tc-late a:hover .arrow { transform: translateX(3px); }

@media (max-width: 760px) {
  /* Twelve columns become a swipeable strip: 12 cells at 375px would be 27px
     wide, under the 44px touch target and unreadable besides. */
  .tc-rail {
    display: flex; overflow-x: auto; scroll-snap-type: x proximity;
    /* Bleed to the wrap's own gutter so the strip runs edge to edge. */
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    /* Without this, every snap rest put a cell's border at screen x=0, which
       reads as "clipped" rather than "continues off-screen". */
    scroll-padding-inline: var(--gutter);
    /* The scrollbar IS the affordance. Hiding it left a half-cut cell as the
       only hint that seven more months exist; a 3px thumb under the axis also
       doubles as "how far through the year you are". */
    scrollbar-width: thin;
    scrollbar-color: var(--border-interactive) var(--hairline);
  }
  .tc-rail::-webkit-scrollbar { height: 3px; }
  .tc-rail::-webkit-scrollbar-track { background: var(--hairline); }
  .tc-rail::-webkit-scrollbar-thumb { background: var(--border-interactive); border-radius: 2px; }
  .tc-rail-cell { flex: 0 0 auto; min-width: 62px; scroll-snap-align: start; }
  .tc-rail-legend { margin-top: 14px; }
}

@media (max-width: 640px) {
  .tc-next { grid-template-columns: 1fr; gap: 16px; padding: 20px 0; }
  .tc-next-date { justify-items: start; }
  .tc-day { grid-template-columns: 1fr; gap: 8px; padding: 16px 0; }
  .tc-date { flex-direction: row; align-items: baseline; flex-wrap: wrap; gap: 8px; }
  .tc-date-num { font-size: 22px; }
  .tc-date-moved { margin-top: 0; flex-basis: 100%; }
  .tc-chip { font-size: 13px; padding: 8px 12px; }
  .tc-cards { margin-top: 40px; }
}

/* Official sources — the tax authority's own tools, under our own answer.
   Echoes the related strip so it reads as family, with one deliberate break:
   no tile. The lime tile is how our own cards announce themselves on hover;
   an outbound card gets an arrow instead, and the visitor can tell at a
   glance whose page a click leads to (panel decision, 2026-09-01). */
.official-sources { margin-top: 56px; }
.official-row { display: flex; flex-wrap: wrap; gap: 10px; }
.official-card {
  flex: 1 1 240px; min-width: 0;
  display: flex; flex-direction: column; gap: 4px;
  padding: 14px 16px;
  border: 1px solid var(--hairline); border-radius: 10px;
  background: var(--bg); color: var(--ink); text-decoration: none;
  transition: transform 250ms ease, border-color 250ms ease, background 250ms ease;
}
.official-card:hover { transform: translateY(-2px); border-color: var(--ink); background: var(--bg-hover); }
.official-card:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.official-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.official-title { font-size: 15px; line-height: 1.35; }
.official-arrow { flex: none; color: var(--ink-secondary); transition: transform 250ms ease; }
.official-card:hover .official-arrow { transform: translate(2px, -2px); }
/* Host and minutes, in the mono face the site uses for metadata: this is a
   label about the link, not part of the sentence. */
.official-host {
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.03em;
  color: var(--ink-secondary);
}
.official-returns { font-size: 13px; line-height: 1.45; color: var(--ink-secondary); }
.official-note {
  margin: 14px 0 0; font-family: var(--mono); font-size: 12px; line-height: 1.6;
  color: var(--ink-secondary);
}
@media (max-width: 640px) {
  .calc-related { margin-top: 44px; }
  .calc-related-card { width: 100%; }
  .calc-related-all { width: auto; }
  /* One per row: three stacked cards is a list, three squeezed side by side
     is a wall. The 44px touch target comes free from the card's own padding. */
  .official-sources { margin-top: 44px; }
  .official-card { flex-basis: 100%; }
}

/* --- Live estimate: gating, card states, sticky bar, a11y ---------------- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* Chip groups are now real fieldsets — kill the browser chrome. */
fieldset.quote-q { border: 0; padding: 0; margin: 0 0 30px; min-width: 0; }
.quote-q legend.intent-legend { display: block; padding: 0; margin-bottom: 10px; }
.quote-step > legend:focus { outline: none; }

/* JS gating: steps swap only when JS runs; without it the whole form +
   single submit is visible and the live card/bar/step-chrome disappear.
   Gated on .quote-js — set by estimator.js only AFTER it has wired
   everything up, NOT the generic .js set inline in <head>. With the
   generic class, a blocked or throwing estimator.js left the quiz stuck on
   step 1 with no submit control at all (expert review 2026-07-24, P0). */
.quote-js .quote-step:not(.active) { display: none; }
html:not(.quote-js) [data-next],
html:not(.quote-js) [data-back],
html:not(.quote-js) .quote-steps,
html:not(.quote-js) .quote-bar,
html:not(.quote-js) .quote-estimate { display: none; }

/* Error summary (server-side re-render) */
.form-errors {
  max-width: 720px; margin: 0 0 28px;
  border: 1px solid var(--danger-border); border-left: 4px solid var(--danger);
  border-radius: 8px; padding: 16px 20px;
}
.form-errors:focus { outline: 2px solid var(--ink); outline-offset: 2px; }
.form-errors-title { font-weight: 600; margin: 0 0 8px; color: var(--danger); }
.form-errors ul { margin: 0; padding-left: 18px; }
.form-errors a { color: var(--danger); }

/* Estimate card states */
.quote-estimate { margin-top: 4px; margin-bottom: 34px; transition: border-color 300ms ease; }
.quote-estimate-placeholder { color: var(--ink-secondary); margin: 2px 0; }
.quote-onetime { margin: 8px 0 0; font-size: 15px; color: var(--ink-secondary); }
.quote-includes { margin: 12px 0 0; padding: 0; list-style: none; }
.quote-includes li {
  display: inline-block; margin: 0 8px 6px 0; padding: 4px 10px;
  border: 1px solid var(--hairline); border-radius: 999px;
  font-size: 13px; color: var(--ink-secondary);
}
.quote-plan-features { margin-top: 16px; }
.quote-features-head {
  margin: 0 0 6px; font-family: var(--mono);
  font-size: 11px; letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary);
}
.quote-plan-features ul { margin: 0; padding: 0; list-style: none; }
.quote-plan-features li {
  position: relative; padding-left: 20px; margin-bottom: 5px;
  font-size: 14px; line-height: 1.5;
}
.quote-plan-features li::before {
  content: "✓"; position: absolute; left: 0; color: var(--accent-ink);
  font-weight: 700;
}
.quote-anchor {
  margin: 14px 0 0; font-family: var(--mono);
  font-size: 12px; color: var(--ink-secondary);
}
/* One quiet value line under the market guide — secondary by design: the
   computed AVH price above stays the loudest element in the card. */
.quote-value-note {
  margin: 8px 0 0; font-size: 13px; line-height: 1.5;
  color: var(--ink-secondary);
}
/* Solo micro-ԱՁ package note: same quiet register as the value line. */
.quote-micro-note { margin: 12px 0 0; }
.quote-micro-note p {
  margin: 0 0 4px; font-size: 13px; line-height: 1.5;
  color: var(--ink-secondary);
}
/* Step-2 reassurance: what-happens-next + switching + WhatsApp escape hatch */
.quote-next-mini {
  margin: 4px 0 16px; padding-left: 20px;
  font-size: 14px; color: var(--ink-secondary);
}
.quote-next-mini li { margin-bottom: 4px; }
.quote-switch {
  margin: 0 0 20px; padding: 10px 14px;
  background: var(--bg-hover); border-radius: 8px;
  font-size: 14px; line-height: 1.5;
}
.quote-wa { margin: 14px 0 0; font-size: 14px; color: var(--ink-secondary); }
.quote-wa a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--hairline); }
.quote-wa a:hover { text-decoration-color: var(--ink); }

/* Sticky mobile estimate bar — e-commerce "total" pattern. Desktop never
   needs it: the card is in view next to the form. */
.quote-bar { display: none; }
@media (max-width: 720px) {
  .js .quote-bar {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    background: var(--bg);
    border-top: 1px solid var(--ink);
  }
  .js .quote-bar[hidden] { display: none; }
  .quote-bar-price { font-weight: 600; font-size: 15px; }
  .quote-bar .btn { flex: none; }
  /* Breathing room so the bar never covers the last controls. */
  .js .quote-page .quote-form,
  .js .calculator-section .quote-form { padding-bottom: 96px; }
  .quote-nav .btn { width: 100%; justify-content: center; }
}

/* Sticky mobile CTA on the home page — appears after the pricing section,
   hides at the contact form. Its own element (NOT .quote-bar, which is the
   quote page's estimate-total bar). Desktop keeps the inline CTAs. */
.cta-sticky { display: none; }
@media (max-width: 720px) {
  .js .cta-sticky:not([hidden]) {
    display: flex; align-items: center; gap: 12px;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    background: var(--bg);
    border-top: 1px solid var(--ink);
  }
  .cta-sticky .btn { flex: 1; justify-content: center; }
  .cta-sticky-wa {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 46px; height: 46px; border-radius: 999px;
    background: var(--bg-hover); color: var(--ink);
    transition: background 150ms ease;
  }
  .cta-sticky-wa:hover { background: var(--hairline); }
}

/* Answers carried over from the home calculator (2026-07-28, 3.1) — a quiet
   confirmation, not a banner: it reassures without competing with the H1. */
.quote-carried {
  display: flex; align-items: baseline; gap: 8px;
  margin: 0 0 28px; padding: 12px 16px;
  background: var(--bg-elevated);
  border-left: 2px solid var(--accent);
  font-size: 14px; color: var(--ink-secondary); max-width: 620px;
}
.quote-carried span { color: var(--ink); }

/* "When shall we call" — date beside the windows on desktop, stacked on
   the phone. */
.callback-row { display: grid; gap: 20px; grid-template-columns: minmax(150px, 200px) 1fr; align-items: start; }
.callback-row .field { margin: 0; }
/* Not a <label> (it names a radio group, not one control), but it sits
   beside one and must read as its twin — same mono caps as .field label. */
.field-label-lite {
  display: block; margin-bottom: 8px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary);
}
@media (max-width: 620px) {
  .callback-row { grid-template-columns: 1fr; gap: 16px; }
}

/* FAQ: questions left, the way out right (2026-07-28, 5.4). Below 1100px the
   aside drops under the list — a sticky rail needs a column to be sticky in. */
.faq-layout { display: grid; gap: 40px; }
@media (min-width: 1100px) {
  .faq-layout { grid-template-columns: 780px minmax(0, 1fr); gap: 64px; align-items: start; }
  .faq-aside { position: sticky; top: 96px; }
}
.faq-aside {
  padding: 28px 24px;
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  display: flex; flex-direction: column; gap: 10px;
}
.faq-aside-title { margin: 0; font-size: 18px; font-weight: 500; letter-spacing: -0.01em; }
.faq-aside-note { margin: 0 0 6px; font-size: 14px; line-height: 1.5; color: var(--ink-secondary); }
.faq-aside .btn { justify-content: center; }

/* =========================================================================
   Service landing pages (2026-07-28, 4.2)
   ========================================================================= */
.service-page { padding-top: 160px; }
.service-layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 64px; align-items: start; }
.service-body { max-width: 68ch; }
.service-body h2 { font-size: 26px; margin: 40px 0 12px; letter-spacing: -0.01em; }
.service-body h2:first-child { margin-top: 0; }
.service-body p { margin: 0 0 16px; line-height: 1.65; color: var(--ink-secondary); }
.service-rail { position: sticky; top: 96px; display: flex; flex-direction: column; gap: 12px; }
.service-price {
  padding: 24px; margin-bottom: 8px;
  background: var(--bg-elevated); border: 1px solid var(--hairline);
}
.service-price h2 { font-size: 18px; margin: 10px 0 6px; }
/* The hub's own copy sits under the cards — the cards are the answer to
   "what do you do", this is the answer to "how does it work". */
.services-hub-body { margin-top: 72px; }
.service-faq { margin-top: 72px; }
.service-faq > h2 { margin-bottom: 20px; }
.service-siblings { margin-top: 64px; padding-top: 24px; border-top: 1px solid var(--hairline); }
.service-siblings ul { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 12px 32px; }
.service-siblings a { font-size: 15px; border-bottom: 1px solid var(--hairline); transition: border-color 200ms ease; }
.service-siblings a:hover { border-color: var(--ink); }
.service-link { display: inline-flex; align-items: baseline; gap: 6px; }
.service-link .arrow { transition: transform 200ms ease; }
.service-card:hover .service-link .arrow { transform: translateX(3px); }
@media (max-width: 1000px) {
  /* The rail stops being a rail: on a narrow screen the price belongs
     after the text that justifies it, not floating beside it. */
  .service-layout { grid-template-columns: 1fr; gap: 40px; }
  .service-rail { position: static; }
}
@media (max-width: 720px) {
  .service-page { padding-top: 120px; }
  .service-body h2 { font-size: 22px; }
}

/* Guides (2026-09-01, promotion plan K2 / spec C-G0).
   The byline and the checked-on line are the guide's only structural
   addition to a service page: on a tax question the reader's first two
   questions are "who says so" and "as of when", and the answers belong
   above the fold, not in a footer. */
.guide-byline {
  display: flex; align-items: center; flex-wrap: wrap; gap: 12px 20px;
  margin: 0 0 48px; padding: 16px 0;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}
.guide-byline img { width: 48px; height: 48px; border-radius: 50%; object-fit: cover; }
.guide-byline-name { margin: 0; font-size: 15px; font-weight: 500; }
.guide-byline-name a { border-bottom: 1px solid var(--hairline); transition: border-color 200ms ease; }
.guide-byline-name a:hover { border-color: var(--ink); }
.guide-byline-role { margin: 2px 0 0; font-size: 13px; color: var(--ink-secondary); }
/* Two classes deep on purpose: the section's own `p` rule is more specific
   than a bare .guide-checked and was winning the font back. */
.guide-byline .guide-checked {
  margin: 0 0 0 auto;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em;
  color: var(--ink-secondary);
}
@media (max-width: 720px) {
  /* Under 720 the row wraps; pinned right would leave the date orphaned. */
  .guide-byline .guide-checked { margin-left: 0; }
}

/* Success page */
.quote-next { max-width: 620px; margin-top: 40px; }
.quote-next-steps { margin: 12px 0 0; padding-left: 20px; }
.quote-next-steps li { margin-bottom: 8px; color: var(--ink-secondary); line-height: 1.55; }

/* =========================================================================
   Legal pages
   ========================================================================= */
.legal-page { padding-top: 160px; border-top: 0; }
.legal-updated { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; }
.legal-body { max-width: 720px; }
.legal-body p { color: var(--ink-secondary); font-size: 16px; line-height: 1.65; margin: 0 0 20px; }

/* =========================================================================
   FAQ — hairline rows
   ========================================================================= */
.faq-list { max-width: 780px; }
.faq-item { border-top: 1px solid var(--hairline); }
.faq-item:last-child { border-bottom: 1px solid var(--hairline); }
.faq-item summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 22px 4px;
  font-size: 18px; font-weight: 500; letter-spacing: -0.01em;
  cursor: pointer; list-style: none;
  min-height: 44px;
  transition: color 150ms ease;
}
.faq-item summary::-webkit-details-marker { display: none; }
/* The question may be a real heading inside the summary (guides do this, and
   K10 does the same to the calculator FAQs): a passage Google can retrieve
   needs a name. It must not look like one. */
.faq-item summary h3 { margin: 0; font: inherit; letter-spacing: inherit; }
.faq-item summary:hover { color: #000; }
.faq-chev { flex: none; color: var(--ink-secondary); transition: transform 200ms ease; }
.faq-item[open] .faq-chev { transform: rotate(180deg); }
.faq-answer { padding: 0 4px 24px; }
.faq-answer p { color: var(--ink-secondary); margin: 0; font-size: 15px; line-height: 1.55; max-width: 62ch; }

.faq-item::details-content {
  block-size: 0;
  overflow: hidden;
  opacity: 0;
  transition: block-size 0.3s var(--ease-out), opacity 0.25s ease,
              content-visibility 0.3s allow-discrete;
}
.faq-item[open]::details-content { block-size: auto; opacity: 1; }

/* =========================================================================
   Contact
   ========================================================================= */
.contact-shell { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: start; }
.contact-info .eyebrow { display: block; margin-bottom: 20px; }
.contact-info h2 { font-size: clamp(36px, 4.5vw, 56px); letter-spacing: -0.03em; line-height: 1.05; text-wrap: balance; overflow-wrap: break-word; }
.contact-info > p { color: var(--ink-secondary); margin: 20px 0 0; max-width: 440px; }
.contact-lines { margin-top: 40px; }
.contact-line {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 24px;
  border-top: 1px solid var(--hairline);
  padding: 16px 4px;
}
.contact-line a { overflow-wrap: anywhere; } /* long emails/hy addresses on 335px */
.office-links { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.office-links .office-building { font-size: 14px; color: var(--ink-secondary); }
.office-links .office-building:hover { color: var(--ink); }
.contact-line:last-child { border-bottom: 1px solid var(--hairline); }
.contact-line small {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary); min-width: 72px;
}
.contact-line span, .contact-line a { font-size: 16px; }
.contact-line a:hover { text-decoration: underline; text-underline-offset: 3px; }
.copy-btn {
  margin-left: auto; padding: 3px 10px;
  border: 1px solid var(--border-interactive); border-radius: 999px;
  background: transparent; cursor: pointer;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
  transition: color 150ms ease, border-color 150ms ease, background 150ms ease;
}
.copy-btn:hover { color: var(--ink); border-color: var(--ink); }
.copy-btn.is-copied { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); }
/* Both clipboard paths refused (in-app WebView) — say so instead of
   looking like a dead button. site.js also selects the value so a
   long-press still works. */
.copy-btn.is-copy-failed { color: var(--danger); border-color: var(--danger-border); background: var(--danger-bg); }

.messenger-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.messenger-row .btn { padding: 11px 18px; font-size: 14px; }
/* Conversion-polished contact: messengers are the primary action. */
.messenger-row--primary .btn { padding: 13px 22px; font-size: 15px; }
.messenger-note { margin: 12px 0 0; font-size: 13.5px; color: var(--ink-secondary); max-width: 400px; }
.contact-quote-bridge {
  margin: 22px 0 0; font-size: 14.5px; color: var(--ink-secondary); max-width: 420px;
}
.contact-quote-bridge a {
  color: var(--ink); font-weight: 500; text-decoration: underline;
  text-underline-offset: 3px; transition: color 200ms ease;
}
.contact-quote-bridge a:hover { color: var(--ink-secondary); }

.contact-map {
  margin-top: 32px;
  border: 1px solid var(--hairline); border-radius: 8px; overflow: hidden;
}
.contact-map iframe { width: 100%; height: 260px; border: 0; display: block; filter: saturate(0.7); }

.contact-form {
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 36px 32px;
}
.field { margin-bottom: 18px; }
.field label {
  display: block;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary); margin-bottom: 8px;
}
.field input, .field textarea {
  width: 100%; padding: 13px 14px;
  font-family: var(--sans); font-size: 16px;
  color: var(--ink); background: var(--bg-elevated);
  border: 1px solid var(--border-interactive); border-radius: 8px;
  transition: border-color 150ms ease;
}
.field input:focus, .field textarea:focus { outline: none; border-color: var(--ink); }
.field textarea { resize: vertical; min-height: 120px; }
.field label .opt { text-transform: none; }
.field.has-error input, .field.has-error textarea { border-color: var(--danger); }
.field-error { color: var(--danger); font-size: 13px; margin: 6px 0 0; }
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.field-hint { color: var(--ink-secondary); font-size: 12.5px; margin: 6px 0 0; }

/* "Attach my question" — the /ask/ → contact handoff (rendered only when
   the visitor arrives via ?src=ask with a transcript in the session) */
.ask-attach-check { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; cursor: pointer; }
.ask-attach-check input { width: 16px; height: 16px; margin-top: 2px; flex: none; accent-color: var(--ink); }
.ask-attach-quote {
  margin: 8px 0 0; padding: 8px 14px;
  border-left: 2px solid var(--hairline);
  color: var(--ink-secondary); font-size: 13.5px; line-height: 1.5;
  overflow-wrap: anywhere;
}

/* Intent chips — one form, four intentions */
.intent-field { border: 0; padding: 0; margin: 0 0 18px; min-width: 0; }
.intent-legend {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary); margin-bottom: 8px; padding: 0;
}
.intent-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.intent-chip { position: relative; }
.intent-chip input { position: absolute; opacity: 0; pointer-events: none; }
/* min-height 44px, not the old ~36: the chips ARE the quiz — ~30 of them are
   the primary input on /quote/, and every other control on the site already
   honours 44 (expert review 2026-07-24, C3). inline-flex keeps the label
   optically centred once the box is taller than its text.
   "> span", never a descendant: the ru/en labels wrap their Armenian
   abbreviation in <span lang="hy"> so a ru screen reader does not mangle it
   (estimator.html), and a descendant selector gave "ООО (ՍՊԸ)" a second
   44px pill around the ՍՊԸ — 64px tall, and still white once the chip
   itself went dark, because :checked + span only reaches the outer one. */
.intent-chip > span {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 9px 16px; border-radius: 999px;
  border: 1px solid var(--border-interactive); background: var(--bg-elevated);
  font-size: 13px; font-weight: 500; line-height: 1.2; color: var(--ink-secondary);
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.intent-chip:hover > span { background: var(--bg-hover); color: var(--ink); }
.intent-chip input:checked + span { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.intent-chip input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 2px; }
.form-note { color: var(--ink-secondary); font-size: 13px; margin-top: 14px; }
.form-note a { text-decoration: underline; text-underline-offset: 2px; }
.btn-block { width: 100%; justify-content: center; }
.btn.is-loading { opacity: 0.7; pointer-events: none; }

.flash { padding: 13px 16px; border-radius: 8px; margin-bottom: 18px; font-size: 14px; border: 1px solid var(--hairline); }
.flash.success { background: rgba(223, 242, 80, 0.25); color: var(--ink); }
.flash.error { background: var(--danger-bg); color: var(--danger); border-color: var(--danger-border); }
.flash.info { background: var(--bg-hover); }

/* Account pages — the lead-form card doubles as the account/auth card. */
.auth-page .wrap { max-width: 640px; }
.auth-card { margin-top: 0; }
/* Google sign-in above the credentials form */
.auth-social { margin-bottom: 24px; }
.auth-social .btn svg { flex: none; }
.auth-divider {
  display: flex; align-items: center; gap: 14px;
  margin: 20px 0 0;
  font-size: 13px; color: var(--ink-secondary);
}
.auth-divider::before, .auth-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--hairline);
}
.account-row {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 16px; flex-wrap: wrap;
  padding: 14px 0; border-bottom: 1px solid var(--hairline);
}
.account-label {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
}
.account-value { font-size: 15px; }
.badge {
  display: inline-block; margin-left: 8px; padding: 3px 10px;
  border-radius: 999px; font-size: 12px; line-height: 1.2;
  border: 1px solid var(--hairline);
}
.badge-ok { background: var(--accent-soft); border-color: transparent; }
.badge-pending { color: var(--ink-secondary); }
.account-action { margin-top: 18px; }

/* =========================================================================
   Footer CTA — the dark bookend
   ========================================================================= */
.footer-cta { text-align: center; padding: 120px var(--gutter) 140px; }
.footer-cta .ticker-line {
  font-family: var(--mono);
  font-size: 12px; letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  color: var(--ink-inverse-2);
  margin: 0 0 28px;
}
.footer-cta h2 {
  font-family: var(--serif); font-weight: 500; font-synthesis: none;
  font-size: clamp(60px, 9.5vw, 136px);
  letter-spacing: -0.02em; line-height: 1;
  margin-bottom: 44px;
}
.btn-accent { background: var(--accent); color: var(--accent-ink); font-weight: 600; }
.btn-accent:hover { background: var(--accent-hover); transform: translateY(-1px); }
/* On dark sections a low marker fails (light glyph-tops unreadable) — but a
   full lime plate was the single largest solid-lime area on the page. Lime
   TYPE on dark green (12:1) is the editorial answer: acid ink, not a slab. */
.inverse .gold, .footer-cta .gold {
  background: none;
  color: var(--accent);
  padding: 0;
  margin: 0;
}

.site-footer { border-top: 1px solid var(--hairline); padding-block: 56px 40px; }
.footer-top { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 40px; align-items: flex-start; }
.footer-brand { max-width: 320px; }
.footer-brand p { color: var(--ink-secondary); font-size: 14px; margin-top: 14px; }
.footer-links { display: flex; gap: 72px; flex-wrap: wrap; }
.footer-col-title {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: var(--label-case, uppercase);
  font-weight: 500; color: var(--ink-secondary); margin: 0 0 14px;
}
.footer-col a, .footer-col .footer-line { display: block; color: var(--ink-secondary); font-size: 14px; font-weight: 500; padding: 4px 0; transition: color 150ms ease; }
.footer-col a:hover { color: var(--ink); text-decoration: none; }
.footer-bottom {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 16px;
  margin-top: 56px; padding-top: 24px; border-top: 1px solid var(--hairline);
  color: var(--ink-secondary); font-size: 13px;
}
.socials { display: flex; gap: 8px; }
.socials a {
  width: 36px; height: 36px; border-radius: 999px;
  display: grid; place-items: center;
  border: 1px solid var(--border-interactive); color: var(--ink-secondary);
  transition: background 150ms ease, color 150ms ease;
}
.socials a:hover { background: var(--bg-hover); color: var(--ink); }

/* =========================================================================
   Scroll reveal — the transition lives only on the hidden state so it never
   overrides hover transitions after the element becomes visible
   ========================================================================= */
/* Gated on html.js (set inline in <head> before this stylesheet loads):
   no-JS visitors must see all content — hiding for the reveal animation is
   an enhancement, not a default. */
html.js [data-reveal]:not(.is-visible) {
  opacity: 0; transform: translateY(24px);
}
[data-reveal].is-visible {
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out),
              background 200ms ease;
}

/* =========================================================================
   Responsive
   ========================================================================= */
@media (max-width: 1100px) {
  /* full hy nav + brand + lang + CTA don't fit around ~900-1000px */
  .header-inner { gap: 20px; }
  .nav { gap: 16px; }
  .services-grid, .testimonial-grid, .pricing-grid { grid-template-columns: repeat(2, 1fr); }
  .team-grid { grid-template-columns: repeat(3, 1fr); }
  /* an odd trailing card spans the full row — no empty gray cell */
  .services-grid > :last-child:nth-child(odd),
  .testimonial-grid > :last-child:nth-child(odd),
  .pricing-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  .team-grid > :last-child:nth-child(3n+1) { grid-column: 1 / -1; }
  .process-step { grid-template-columns: 90px 1fr; }
  .process-step p { grid-column: 2; padding-top: 0; }
}
@media (max-width: 1000px) {
  .nav-cta { display: none; } /* the hero CTA takes over; menu CTA below 860 */
}
@media (max-width: 860px) {
  :root { --gutter: 20px; }
  .team-grid { grid-template-columns: repeat(2, 1fr); }
  .block, .inverse-grid { padding-block: 72px; }
  .block--tight { padding-block: 56px; }
  .section-head { margin-bottom: 40px; }
  .hero-inner { padding-block: 128px 64px; }
  .hero h1 { font-size: clamp(44px, 12vw, 72px); }
  .footer-cta { padding-block: 72px 88px; }

  .contact-shell, .inverse-grid { grid-template-columns: 1fr; gap: 48px; }
  .stat-list { gap: 28px; }
  .gallery-grid { columns: 2 180px; }

  .nav { display: none; }
  .menu-toggle { display: grid; place-items: center; }
  .header-inner { gap: 12px; }
  .header-right { gap: 10px; }
  .lang-switch { display: none; } /* languages live inside the menu on mobile */
  .site-header.open .nav {
    display: flex; flex-direction: column; align-items: flex-start;
    position: absolute; top: 64px; left: 0; right: 0;
    background: var(--bg);
    padding: 20px var(--gutter) 28px; gap: 4px;
    border-bottom: 1px solid var(--hairline);
    animation: menuIn 250ms var(--ease-out);
    /* The panel hangs off a position:fixed header, so page scroll cannot
       move it: on a landscape phone (~375px tall) the links, the CTA and
       the language row ran past the viewport and were unreachable (expert
       review 2026-07-24, P0). dvh follows the collapsing mobile URL bar;
       the vh line above it is the fallback for older iOS. */
    max-height: calc(100vh - 64px);
    max-height: calc(100dvh - 64px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .site-header.open .nav > a { font-size: 16px; padding: 10px 0; width: 100%; }
  .nav-cta { display: none; }
  .site-header.open .nav-mobile-extra {
    display: flex; flex-direction: column; gap: 16px;
    width: 100%; margin-top: 16px; padding-top: 20px;
    border-top: 1px solid var(--hairline);
  }
  .site-header.open .nav-mobile-extra .btn { justify-content: center; }
}
@keyframes menuIn { from { opacity: 0; transform: translateY(-8px); } }
@media (max-width: 640px) {
  .services-grid, .testimonial-grid, .video-grid, .team-grid, .pricing-grid, .standards-grid { grid-template-columns: 1fr; }
  .services-grid > :last-child:nth-child(odd),
  .testimonial-grid > :last-child:nth-child(odd),
  .pricing-grid > :last-child:nth-child(odd),
  .team-grid > :last-child:nth-child(3n+1) { grid-column: auto; }
  /* Stacked: label on top, strip under it. The pause button rides on the
     label line rather than claiming a third row of its own. */
  .marquee { position: relative; flex-direction: column; align-items: flex-start; gap: 16px; }
  /* flex-start sizes the viewport to its content on the cross axis, and the
     track is width:max-content — so the strip grew to ~1139px inside a 375px
     section. It was invisible (the section clips it), but the mask's 92% fade
     stop went with it: the right edge cut off hard instead of fading. */
  .marquee-viewport { align-self: stretch; }
  .js .marquee-pause { position: absolute; top: 10px; right: var(--gutter); }
  /* Price must hold one line in all three locales (hy "25 000 ֏-ից / ամիս"
     is the widest); admin can change amounts, so scale with the viewport.
     The nowrap is scoped to the PLAN CARDS, where the amount is a number.
     The estimate card reuses .pricing-price for a whole sentence — hy
     "սկսած 35 000 ֏՝ ամսական" is 363px at this size — and nowrap there made
     that sentence the card's min-content width: the flex body could not
     shrink below it, so the price, the chips and every note in the card ran
     70px past the border and off the phone (owner report 2026-07-25, real
     device). Now it wraps to two lines and nothing leaves the frame. */
  .pricing-price .amount { font-size: clamp(22px, 7.5vw, 32px); }
  .pricing-card .pricing-price { flex-wrap: nowrap; }
  .pricing-card .pricing-price .amount { white-space: nowrap; }
  .pricing-card .pricing-price .period { flex: none; white-space: nowrap; }
  /* Shorter cards on the phone stack (audit П7-lite): the absolute badge
     becomes a static chip above the title, and features 4+ sit behind
     an "All features" disclosure. */
  .pricing-tag { position: static; align-self: flex-start; }
  .pricing-card.popular h3 { padding-right: 0; }
  .pricing-features-more > summary {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    min-height: 44px; padding: 9px 0;
    border-top: 1px solid var(--hairline);
    font-size: 14px; color: var(--ink-secondary);
  }
  .pricing-features-more[open] > summary { border-bottom: 0; }
}
@media (max-width: 520px) {
  body { font-size: 16px; }
  /* 40px of side padding on a 335px sheet left 255px for a label and a
     seven-digit amount — the tightest box on the phone. 20px gives the row
     40px more to work with (audit 2026-07-25). */
  .report-sheet { padding: 28px 20px 24px; }
  .report-row { gap: 12px; }
  .brand { font-size: 16px; }
  .brand img { height: 24px; }
  .brand .mark { width: 24px; height: 24px; font-size: 0.75rem; }
  .hero h1 { font-size: clamp(38px, 12vw, 56px); }
  /* Shorter hero on phones so the CTA sits nearer the fold; a full-width
     primary button is the easiest thumb target */
  .hero-inner { padding-block: 96px 56px; }
  .hero-actions { gap: 14px; }
  .hero-actions .btn-primary { width: 100%; justify-content: center; }
  .btn { padding: 13px 20px; }
  .process-step { grid-template-columns: 56px 1fr; gap: 16px; padding: 24px 4px; }
  .process-num { font-size: 40px; }
  .marquee-track { gap: 48px; }
  .stat .value { font-size: 36px; }
  .footer-links { gap: 40px; }
  .footer-cta h2 { font-size: clamp(44px, 13vw, 64px); }
  /* uppercase hy labels don't fit a 335px chat card — drop the caps styling */
  .chat-line > span:first-child { text-transform: none; letter-spacing: 0.02em; font-size: 11.5px; }
  .chat-app-net { display: none; } /* competes with the bot name for width */
}

/* ---- Per-language typography tuning ----

   Armenian is the PRIMARY language, but the type system was authored for
   Latin: the display scale, the label voice and the marker geometry all
   degraded when translated (expert design review 2026-07-24). Three fixes
   live below — display tier, label voice, marker.

   NOT done, deliberately: switching the hy hero to var(--serif) as the
   footer does. The hero headline carries a .gold accent whose only
   distinction in Armenian is being serif — there is no
   noto-serif-armenian-italic file and font-synthesis is off, so the italic
   never renders. A serif headline would make the accent vanish into its
   own sentence. The display tier is built from SIZE instead. */

/* B1 — display tier. Was clamp(38px, 4.7vw, 56px), i.e. exactly the size
   of every section h2 below it: the page had no focal point above the
   fold. The hero now outranks section heads roughly 1.5:1. */
html[lang="hy"] .hero h1 {
  font-size: clamp(44px, 6.5vw, 84px);
  line-height: 1.08; letter-spacing: -0.02em;
  /* lang="hy" is set on <html>, so the hyphenation dictionary applies —
     better than break-word, which split հաշվապահությունը mid-glyph with
     no hyphen in the first line a visitor reads. */
  hyphens: auto;
}
html[lang="hy"] .section-head h2 { font-size: clamp(32px, 3.4vw, 44px); }
html[lang="hy"] h2, html[lang="hy"] h3 { line-height: 1.18; letter-spacing: -0.01em; }

/* B2 — label voice. Armenian has no monospace face (the --mono stack falls
   through to Noto Sans Armenian), so every eyebrow, form label, legend and
   badge rendered as proportional sans in ALL CAPS with 0.06–0.1em tracking
   — the worst possible treatment for a script whose caps carry no
   ascender/descender variety. Sentence case, tighter, slightly bolder.
   --label-case is read by all 22 uppercase declarations in this file. */
html[lang="hy"] {
  --label-case: none;
  /* digits from SF Mono next to Armenian from Noto Sans made "45 000 ֏-ից"
     two visibly different weights; one family + tabular figures instead. */
  --mono: 'Instrument Sans', 'Manrope', 'Noto Sans Armenian', sans-serif;
}
html[lang="hy"] .eyebrow,
html[lang="hy"] .tools-group,
html[lang="hy"] .ticker-line,
html[lang="hy"] .intent-legend,
html[lang="hy"] .field label,
html[lang="hy"] .calc-input label,
html[lang="hy"] .calc-group-cap,
html[lang="hy"] .calc-advanced-cap,
html[lang="hy"] .calc-answer .k,
html[lang="hy"] .calc-sticky .k,
html[lang="hy"] .footer-col-title,
html[lang="hy"] .risk-label,
html[lang="hy"] .service-index,
html[lang="hy"] .bot-tag {
  letter-spacing: 0.02em;
  font-weight: 600;
}
html[lang="hy"] .pricing-price .amount,
html[lang="hy"] .report-val { font-variant-numeric: tabular-nums; }

/* B4 — marker geometry. Armenian marker geometry: Noto's content box is
   ~12% taller than latin faces, so the same % lands lower. At 60% the bar
   crossed the glyphs and read as a strikethrough rather than a highlight;
   drop it under the baseline and thin it. */
html[lang="hy"] .gold { --marker-y: 82%; --marker-h: 0.30em; }
/* Numerals inside an Armenian heading accent. --serif is
   'Cormorant Garamond', 'Noto Serif Armenian', … and the browser picks per
   character by unicode-range: Noto Serif Armenian is subset to the Armenian
   block alone, while Cormorant covers U+0000-00FF — the digits. So an
   accent like "2 րոպեում" drew its letters in Noto Serif Armenian and its
   digit in Cormorant *italic*: a light latin serif with a much smaller
   body, slanted next to upright Armenian. The 2 read as a footnote marker
   (owner report 2026-07-25). Cormorant is dropped from the stack here so
   the numeral falls to the heading's own sans and matches its neighbours;
   the Armenian letters still get their serif, which is what the accent is. */
html[lang="hy"] .hero h1 .gold,
html[lang="hy"] h2 .gold {
  font-size: 1em;
  font-family: 'Noto Serif Armenian', var(--sans);
}
/* …and serifness alone is not an accent. Armenian has no italic face, so on
   hy the highlighted word differed from its neighbours by nothing a reader
   notices at 84px — the comment above admits as much ("the only distinction
   is being serif"). ru/en get true Cormorant italic and read instantly.
   The fix keeps the system's own vocabulary rather than inventing one:
   the drawn lime marker moves onto the hero, where it lands on the first
   screen instead of the third, and every other hy accent gets the lime
   underline the active nav item already uses. The "one marker per page"
   rule survives — it just points at the headline now
   (expert review 2026-07-28, 5.1 + 5.2). */
html[lang="hy"] .hero h1 .gold {
  background: linear-gradient(var(--accent-soft), var(--accent-soft))
              0 var(--marker-y) / calc(var(--marker-draw, 1) * 100%) var(--marker-h) no-repeat;
  padding-inline: 0.1em; margin-inline: -0.1em;
}
/* The marker was the digital section's; on hy it now belongs to the hero,
   and this heading joins the underline family with the rest. */
html[lang="hy"] #digital h2 .gold {
  background: none;
  padding-inline: 0; margin-inline: 0;
}
html[lang="hy"] h2 .gold {
  /* A 2px rule under the word: 3px below the box, pulled in 1px so it stops
     short of the padding — the same gesture as the active nav link. */
  box-shadow: 0 3px 0 -1px var(--accent);
}
html[lang="hy"] .inverse h2 .gold {
  /* On the dark capitulum the accent already carries colour (.inverse .gold),
     so a second signal would shout. */
  box-shadow: none;
}
html[lang="ru"] .hero h1 { font-size: clamp(42px, 5.2vw, 64px); letter-spacing: -0.03em; }
html[lang="ru"] h2 { letter-spacing: -0.02em; }
/* These language overrides out-rank the generic mobile h1 rules above
   (html[lang] .hero h1 beats .hero h1 inside any media query), so the
   mobile sizes must be restated per language. */
/* hy hero was 10.5vw here. Measured at 390px: the headline's longest word
   (հաշվապահությունը, 16 glyphs) renders ~9.98× the font size, so 10.5vw
   makes it ~105% of the viewport — it could NOT fit at any width in this
   range and was hard-broken mid-glyph as հաշվապահությու/նը, with no hyphen
   (Chrome ships no Armenian hyphenation dictionary, so `hyphens: auto`
   alone cannot fix it). 8.5vw keeps the longest word whole from 360px up.
   overflow-wrap: break-word stays as the safety net for editor-entered
   headlines with even longer words — it just no longer fires on ours. */
@media (max-width: 860px) {
  html[lang="hy"] .hero h1 { font-size: clamp(34px, 8.5vw, 64px); }
  html[lang="ru"] .hero h1 { font-size: clamp(40px, 11vw, 68px); }
}
@media (max-width: 520px) {
  html[lang="hy"] .hero h1 { font-size: clamp(30px, 8.5vw, 44px); }
  html[lang="ru"] .hero h1 { font-size: clamp(34px, 11vw, 50px); }
}

/* =========================================================================
   Editorial polish pass (2026-07): drawn rules, receipt calculator,
   micro-case proof row, ink details, page crossfade.
   ========================================================================= */

/* Drawn hairlines — the marker-draw motif generalized: the ledger rules
   itself as you read.

   Registering both properties is what makes them *transitionable* — that is
   the whole reason GSAP was here (expert review 2026-07-24, D2). inherits
   is true on purpose: the rules are drawn on ::before pseudo-elements,
   which read the value from their originating .stat / .process-step.
   initial-value 1 = fully drawn, so no JS, no @property support and
   reduced motion all land on the finished state. site.js arms an element
   to 0 only when it is also able to release it. */
@property --marker-draw { syntax: "<number>"; inherits: true; initial-value: 1; }
@property --rule-draw   { syntax: "<number>"; inherits: true; initial-value: 1; }

/* Arming must NOT be animated — the transition belongs to the release.
   With it declared here the 1→0 arming itself transitioned, so the marker
   was painted full, wiped itself, then drew back in. The values snap to 0,
   and the transition only exists in the .is-drawn state; a transition is
   started from the after-change style, so declaring both together is what
   animates the release. */
.is-drawing { --marker-draw: 0; --rule-draw: 0; }
.is-drawing.is-drawn {
  --marker-draw: 1;
  --rule-draw: 1;
  /* --draw-delay staggers siblings within one batch (set by site.js). */
  transition-property: --marker-draw, --rule-draw;
  transition-duration: 900ms, 800ms;
  transition-timing-function: cubic-bezier(0.65, 0, 0.35, 1), var(--ease-out);
  transition-delay: calc(150ms + var(--draw-delay, 0ms)), var(--draw-delay, 0ms);
}

.stat { border-top: 0; position: relative; }
.stat::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: var(--hairline-inv);
  transform: scaleX(var(--rule-draw, 1)); transform-origin: left;
}
.process-step { border-top: 0; position: relative; }
.process-step::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: var(--hairline);
  transform: scaleX(var(--rule-draw, 1)); transform-origin: left;
}

/* #calculator — the estimate reads as a receipt: mono tabular numerals and
   hairline line items, the ledger idiom of the assistant chat. */
.calculator-section .quote-estimate-result .pricing-price .amount {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 26px; letter-spacing: -0.01em;
}
.calculator-section .quote-includes li { border-top: 1px solid var(--hairline); }
.calculator-section .quote-includes li:first-child { border-top: 0; }
/* A quiet tick when the number changes (estimator.js re-arms the class). */
.quote-estimate .amount.is-updated { animation: estTick 300ms var(--ease-out); }
@keyframes estTick {
  from { opacity: 0.35; transform: translateY(4px); }
}

/* Ink details: prose links underline in hairline and ink up on hover. */
main p a:not(.btn), main li a:not(.btn) {
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: var(--hairline);
  transition: text-decoration-color 150ms ease;
}
main p a:not(.btn):hover { text-decoration-color: var(--ink); }
/* The highlighter grazes the margin: a 2px accent rule on card hover. */
.service-card { position: relative; }
.service-card::before {
  content: ""; position: absolute; left: 0; top: 28px; bottom: 32px; width: 2px;
  background: var(--accent);
  transform: scaleY(0); transform-origin: top;
  transition: transform 150ms var(--ease-out);
}
.service-card:hover::before { transform: scaleY(1); }

/* Marquee logos join the ink system; full color returns on hover. */
.marquee .logo img { transition: filter 200ms ease, opacity 200ms ease; }
.marquee .logo:hover img { filter: none; opacity: 1; }

/* Cross-page crossfade (View Transitions API) — progressive enhancement;
   wrapped in the motion query so reduced-motion never sees it. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  .site-header { view-transition-name: site-header; }
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 250ms;
    animation-timing-function: var(--ease-out);
  }
}

/* ---- Reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition-duration: 0.01ms !important; }
  html { scroll-behavior: auto; }
  /* must outweigh the html.js hiding rule (equal specificity, later order) */
  html.js [data-reveal]:not(.is-visible) { opacity: 1; transform: none; }
  .marquee-track { animation: none !important; }
  .marquee .logo[aria-hidden="true"] { display: none; } /* no dead clipped duplicates */
  .js .marquee-pause { display: none; }  /* nothing left to pause */
  .striped::before { animation: none !important; }
  .chat-typing { display: none; } /* dialog shows finished; no frozen dots */
}

/* =========================================================================
   Calculator print shell + shared additions (calculators plan, wave A)
   ========================================================================= */
.calc-sources {
  color: var(--ink-secondary); font-size: 12px; margin-top: 8px;
  font-family: var(--mono); letter-spacing: 0.01em;
}
.calc-print { margin-top: 16px; align-self: flex-start; }
.calc-print-meta, .calc-print-data, .calc-print-brand { display: none; }

@media print {
  @page { margin: 12mm 14mm 15mm; } /* Chrome's own header/footer live in this band */

  /* site.js keeps [data-reveal] at opacity 0 until the IntersectionObserver
     fires — anything below the fold would print blank without this. */
  [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }

  html, body { background: #fff !important; color: #000 !important; }
  body { font-size: 10pt; line-height: 1.5; }

  /* Screen chrome + marketing: gone. The form prints as echoed text instead. */
  .site-header, .skip-link, .footer-cta, .site-footer,
  .calc-cta, .calc-breadcrumb, .calc-mode, .calc-print, .calc-seo, .calc-related,
  .calc-share, .official-sources,
  /* :not() on the intro paragraph — the letterhead is also a .section-head p
     and would otherwise lose to this rule on specificity (verified by an
     actual print-to-PDF: the brand line vanished). */
  /* The rail is an index into the list printed right below it, and its
     pills lose their fill on paper, so it prints as a row of empty rings
     restating dates the sheet already carries. */
  .tc-rail, .tc-rail-legend,
  /* The chips are a control, and on paper an unticked radio says
     nothing about what the sheet below it actually contains. What it
     was filtered to prints as text in .calc-print-data instead. */
  .tc-filter,
  .calc-form, .section-head .eyebrow,
  .section-head p:not(.calc-print-brand) { display: none !important; }

  .block { padding-block: 0; border-top: 0; }
  .calc-page { padding-top: 0; }
  .wrap { max-width: none; padding-inline: 0; }

  /* ---- Letterhead ---- */
  .calc-print-brand {
    display: block !important;
    font-family: var(--mono); font-size: 8pt; font-weight: 500;
    letter-spacing: 0.1em; text-transform: uppercase; color: #000;
    margin: 0 0 12pt; padding-bottom: 6pt; border-bottom: 0.75pt solid #000;
  }
  .section-head { display: block; margin: 0 0 14pt; }
  .section-head h1 {
    font-size: 16pt; line-height: 1.15; letter-spacing: -0.01em;
    max-width: none; margin: 0;
  }

  /* ---- "Your data": JS-filled label -> value rows, zero input chrome ---- */
  .calc-print-data { display: block !important; margin: 0 0 14pt; break-inside: avoid; }
  .calc-print-cap {
    font-family: var(--mono); font-size: 7.5pt; letter-spacing: 0.08em;
    text-transform: var(--label-case, uppercase); color: #555; margin: 0 0 3pt;
  }
  .calc-print-rows > div {
    display: flex; justify-content: space-between; align-items: baseline; gap: 16pt;
    padding: 3.5pt 0; border-top: 0.5pt solid #ccc; font-size: 9pt;
    break-inside: avoid;
  }
  .calc-print-rows > div:first-child { border-top: 0; }
  .calc-print-rows .k { color: #333; flex: 1; min-width: 0; overflow-wrap: anywhere; }
  .calc-print-rows .v {
    font-family: var(--mono); font-variant-numeric: tabular-nums;
    white-space: nowrap; color: #000;
  }

  /* ---- Results: the document's centrepiece, bracketed by two black rules ---- */
  .calc-shell { display: block; background: none; border: 0; max-width: none; }
  .calc-shell > * { background: none; border: 0; border-radius: 0; padding: 0; margin: 0; }
  .calc-results { display: block; border-top: 1pt solid #000; padding-top: 2pt; break-inside: avoid; }
  .calc-row {
    padding: 4.5pt 0; border-top: 0.5pt solid #ccc; font-size: 10pt;
    break-inside: avoid;
  }
  .calc-row:first-child { border-top: 0; padding-top: 4.5pt; }
  .calc-row .k { color: #333; }
  /* The screen's acid marker under the total is a web flourish — on an
     accountant's sheet it reads as damage. Bold + rules carry it instead. */
  .calc-row .v, .calc-results .gold { color: #000 !important; background: none !important; }
  .calc-row--total {
    border-top: 1pt solid #000; margin-top: 2pt; padding-top: 5.5pt;
    font-size: 11pt; font-weight: 600;
  }
  .calc-row--total .v { font-size: 13pt; }
  /* The three tiers collapse back to document scale on paper: the
     answer keeps the black rule it earned, not the 46px. */
  .calc-sticky { display: none !important; }
  .calc-answer {
    border-bottom: 0; border-top: 1pt solid #000;
    margin-top: 2pt; padding-top: 5.5pt; break-inside: avoid;
  }
  .calc-answer .k { display: inline; font-size: 8pt; color: #333; margin: 0; }
  .calc-answer .v { display: inline; float: right; font-size: 13pt; font-weight: 600; }
  .calc-group-cap {
    font-size: 7.5pt; letter-spacing: 0.08em; color: #555;
    margin: 6pt 0 3pt; padding-bottom: 2pt; border-bottom: 0.5pt solid #999;
  }
  .calc-breakdown { margin-top: 6pt; }
  .calc-footnotes { margin-top: 6pt; padding-top: 4pt; border-top: 0.5pt solid #999; }
  .calc-note { font-size: 8pt; color: #444; max-width: none; margin-top: 6pt; }

  /* ---- Colophon: URL with query state, date, rates, sources, disclaimer ---- */
  .calc-print-meta {
    display: block; margin-top: 16pt; padding-top: 6pt;
    border-top: 0.75pt solid #000; font-size: 8pt; color: #333;
    break-inside: avoid;
  }
  .calc-print-meta p { margin: 0 0 3pt; }
  .calc-print-meta strong { color: #000; }
  .calc-print-meta [data-print="url"] { overflow-wrap: anywhere; font-family: var(--mono); }

  /* ---- Hub grid -> plain list. Every selector here is tool*/tools*, so the
     .calc-* sheet above is untouched and the A4 calculation sheets of every
     calculator page render byte-identically. ---- */
  .tools-section + .tools-section { margin-top: 8pt; }
  .tools-group {
    font-size: 8pt; margin: 0 0 4pt; padding-bottom: 3pt;
    border-bottom: 0.5pt solid #000;
  }
  .tools-grid { display: block; }
  .tool-card {
    display: block; border: 0; border-radius: 0; padding: 0 0 5pt;
    transform: none !important; break-inside: avoid;
  }
  .tool-head { display: none; }
  .tool-card h3 { font-size: 11pt; margin: 0; }
  .tool-card p { font-size: 9pt; color: #333; margin: 1pt 0 0; }
  .tool-out {
    display: block; border-top: 0; padding-top: 1pt;
    font-size: 8.5pt; color: #333;
  }
  .tool-out .arrow { display: none; }
}

/* ---------- Work calendar page ---------- */
.cal-summary { display: flex; flex-wrap: wrap; gap: 12px 48px; margin: 8px 0 4px; }
.cal-stat .v {
  display: block; font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: clamp(30px, 4vw, 44px); letter-spacing: -0.02em; color: var(--ink);
}
.cal-stat .k { font-size: 13px; color: var(--ink-secondary); }
.cal-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 1px; background: var(--hairline); border: 1px solid var(--hairline);
  margin-top: 32px;
}
.cal-month { background: var(--bg-elevated); padding: 18px 16px 14px; }
.cal-month h3 { font-size: 15px; font-weight: 600; margin: 0 0 10px; }
.cal-grid-head { font-size: 20px; font-weight: 600; margin: 0 0 18px; }
.cal-month table { width: 100%; border-collapse: collapse; }
.cal-month th {
  font-family: var(--mono); font-size: 10px; font-weight: 500;
  letter-spacing: 0.06em; text-transform: var(--label-case, uppercase);
  color: var(--ink-secondary); padding: 2px 0 6px; text-align: center;
}
.cal-month td {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 12px; text-align: center; padding: 3px 0; color: var(--ink);
}
.cal-month td.cal-we { color: var(--ink-secondary); opacity: 0.55; }
.cal-month td.cal-hol {
  color: var(--accent-ink);
  background: linear-gradient(var(--accent-soft), var(--accent-soft))
              center / 22px 18px no-repeat;
}
.cal-month td.cal-wk { text-decoration: underline; text-underline-offset: 2px; }
.cal-month-total {
  margin: 10px 0 0; font-family: var(--mono); font-size: 12px;
  color: var(--ink-secondary); border-top: 1px solid var(--hairline); padding-top: 8px;
}
.cal-legend { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 16px;
  font-size: 13px; color: var(--ink-secondary); }
.cal-legend span { display: inline-flex; align-items: center; gap: 8px; }
.cal-dot { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.cal-dot--hol { background: var(--accent-soft); }
.cal-dot--we { background: var(--hairline); }
.cal-dot--wk { background: transparent; border-bottom: 2px solid var(--ink); border-radius: 0; height: 8px; }
.cal-holidays { margin-top: 56px; max-width: 640px; }
.cal-holidays h2 { font-size: clamp(22px, 3vw, 28px); letter-spacing: -0.02em; margin-bottom: 16px; }
.cal-holidays-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.cal-holidays-table th {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
  text-align: left; padding: 0 12px 8px 0; border-bottom: 1px solid var(--hairline);
}
.cal-holidays-table td { padding: 10px 12px 10px 0; border-bottom: 1px solid var(--hairline); vertical-align: top; }
.cal-holidays-table td:first-child { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }

@media print {
  /* One portrait A4/Letter year sheet: 4x3 month grid at wall-calendar sizes. */
  .cal-summary { gap: 6pt 24pt; margin: 0 0 4pt; }
  .cal-stat .v { font-size: 14pt; }
  .cal-stat .k { font-size: 7.5pt; color: #333; }
  .cal-grid {
    grid-template-columns: repeat(4, 1fr); gap: 0;
    background: none; border: 0.5pt solid #999; margin-top: 8pt;
  }
  .cal-month { background: none; border: 0.5pt solid #bbb; padding: 5pt 5pt 4pt; break-inside: avoid; }
  .cal-month h3 { font-size: 9pt; margin-bottom: 4pt; }
  .cal-grid-head { font-size: 11pt; margin: 0 0 6pt; }
  .cal-month th { font-size: 5.5pt; color: #555; padding: 1pt 0 3pt; }
  .cal-month td { font-size: 7pt; padding: 1.5pt 0; color: #000; }
  .cal-month td.cal-we { color: #888; opacity: 1; }
  .cal-month td.cal-hol { background: none; color: #000; outline: 0.75pt solid #000; outline-offset: -2pt; }
  .cal-month-total { font-size: 6.5pt; margin-top: 4pt; padding-top: 3pt; border-top: 0.5pt solid #ccc; color: #333; }
  .cal-legend { display: flex; gap: 12pt; margin-top: 6pt; font-size: 7.5pt; color: #333; }
  .cal-dot { width: 6pt; height: 6pt; border-radius: 0; }
  .cal-dot--hol { background: none; outline: 0.75pt solid #000; outline-offset: -1.5pt; }
  .cal-dot--we { background: none; border: 0.5pt solid #999; }        /* bg won't print */
  .cal-dot--wk { background: none; border: 0; border-bottom: 1.5pt solid #000; height: 4pt; }
  .cal-holidays { display: none; } /* the grid + legend carry it; keep one page */

  /* The flow diagram is content, not chrome, so it prints. On paper the
     refusal cannot rely on red (many printers are mono and the red goes to a
     mid grey that reads as "less important" — the opposite of the point), so
     it prints black with a rule beside it. */
  .pflow-track { grid-template-columns: 1fr auto 1fr auto 1fr; gap: 8pt; }
  .pflow { background: none; border: 0.5pt solid #999; padding: 8pt 9pt; break-inside: avoid; }
  .pflow-node { background: none; border: 0; padding: 0; }
  .pflow-node--core { padding-left: 6pt; border-left: 1pt solid #000; }
  .pflow-kicker { font-size: 7pt; color: #333; margin-bottom: 4pt; }
  .pflow-node p, .pflow-gate p { font-size: 8pt; color: #000; }
  .pflow-link svg { transform: none; width: 12pt; height: 12pt; }
  .pflow-gate { border-left: 1pt solid #000; padding-left: 8pt; margin-top: 12pt; }
  .pflow-no { color: #000; font-weight: 600; }
  .pflow figcaption { font-size: 7.5pt; color: #333; }
}

/* ── /ask/ — tax-law chat assistant (2026-08-03, reworked 2026-08-05) ─────
   The window IS the page. Owner note: the old head spent the whole first
   viewport explaining the assistant in a lede that the greeting bubble then
   repeated word for word, and the window itself opened below the fold at
   720×320. Now: a title + fact row, then a wide window that starts on screen,
   an empty state instead of a wall-of-text greeting, and a real composer. */
/* The head's top padding and the gap under it always move together — every
   viewport that trims one trims the other — so they are one scale declared
   here and only re-pointed by the queries at the end of this block. Keeps
   padding-top and margin-bottom written once each instead of four times. */
.ask-page { --ask-pad: clamp(104px, 11vw, 128px); --ask-gap: 28px; padding-top: var(--ask-pad); }
.ask-head { margin-bottom: var(--ask-gap); }
.ask-head h1 {
  font-size: clamp(30px, 3.6vw, 44px);
  letter-spacing: -0.03em; line-height: 1.08;
  max-width: 18ch; text-wrap: balance;
  overflow-wrap: break-word; /* 15–20-glyph Armenian words vs 335px screens */
}
/* Proof, not prose: the three things a visitor asks before typing, in the
   space one sentence of the old lede used. */
.ask-facts {
  list-style: none; margin: 14px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
}
.ask-facts li { display: flex; align-items: center; gap: 8px; }
.ask-facts li + li::before {
  content: ""; width: 3px; height: 3px; border-radius: 999px;
  background: currentColor; opacity: 0.5;
}

/* Private-beta strip: seen only by the beta accounts, so it says the one
   thing they cannot see for themselves — that the public gets a 503 here.
   A left rule instead of a filled callout: this is a note to the owner, not
   an alert, and a coloured box would out-shout the H1 it sits under. */
.ask-beta {
  width: min(880px, 100%); margin: 14px 0 0; padding: 8px 0 8px 14px;
  border-left: 2px solid var(--accent, currentColor);
  font-family: var(--mono); font-size: 11px; line-height: 1.7;
  letter-spacing: 0.02em; color: var(--ink-secondary);
}
.ask-beta b { color: var(--ink); font-weight: 600; }

/* Left-anchored like every other block on the site — a centred window under a
   left-aligned title staggered the two edges for no reason. */
.ask-shell { display: flex; flex-direction: column; align-items: flex-start; }
.chat-app--ask { width: min(880px, 100%); }
.chat-app--ask .chat-app-body {
  min-height: clamp(340px, 42vh, 460px); max-height: 62vh; overflow-y: auto;
  padding: 22px 22px 24px;
  display: flex; flex-direction: column; gap: 12px;
  /* No scroll-behavior: smooth here. The JS positions a new answer by its
     top edge, and an animated scrollTop makes that position a promise the
     box does not keep — an interrupted animation leaves the visitor at the
     old offset. Anchors elsewhere still scroll smoothly (html rule). */
}
.ask-cites { display: block; margin-top: 8px; }
.ask-cites a { color: inherit; text-decoration: underline; }

/* Reading type: the demo's 12.5px mono suits three-word ledger lines, not
   multi-paragraph legal answers. Mono stays for captions and citations. */
.chat-app--ask .chat-app-body { font-family: inherit; font-size: 15px; line-height: 1.6; }
.chat-app--ask .chat-bot { width: auto; max-width: 65ch; }
.chat-app--ask .chat-note { font-family: var(--mono); }

/* Citation chips — honest (no stale deep links) and tappable-size */
.ask-cite {
  display: inline-block; margin: 2px 4px 2px 0; padding: 2px 9px;
  border: 1px solid var(--hairline); border-radius: 999px;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.02em;
}
.ask-verify { white-space: nowrap; }

/* The conversion moment gets a real control, not fine print */
.chat-app--ask .ask-consult {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 8px;
  padding: 9px 16px; border: 1px solid var(--border-interactive); border-radius: 999px;
  font-family: inherit; font-size: 13.5px; font-weight: 500; letter-spacing: 0;
  color: var(--ink); text-decoration: none;
  transition: background 200ms ease, border-color 200ms ease;
}
.chat-app--ask .ask-consult:hover { background: var(--bg-hover); border-color: var(--ink-secondary); text-decoration: none; }

/* The answered case gets a line, not a control: it must be findable without
   competing with the answer it sits under, so an underline that thickens on
   hover — never the pill, which is reserved for "the codes came up empty". */
.ask-followup {
  display: inline-block; margin-top: 10px; align-self: flex-start;
  font-size: 13px; color: var(--ink-secondary);
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: var(--hairline);
  transition: color 200ms ease, text-decoration-color 200ms ease;
}
.ask-followup:hover { color: var(--ink); text-decoration-color: var(--ink); }

/* Empty state — the first screen of the window. `margin: auto 0` centres it
   in the (taller) body; once a question is asked JS removes the whole block
   and the transcript takes the room. */
.ask-empty { margin: auto 0; display: flex; flex-direction: column; gap: 22px; }
.ask-empty-lede {
  margin: 0; max-width: 40ch;
  font-family: var(--serif); font-weight: 500; font-synthesis: none;
  font-size: clamp(19px, 1.8vw, 23px); line-height: 1.35; letter-spacing: -0.01em;
  text-wrap: pretty;
}
.ask-starters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.ask-starter {
  position: relative;
  display: flex; flex-direction: column; align-items: flex-start; gap: 7px;
  padding: 14px 34px 15px 16px; text-align: left; cursor: pointer;
  background: var(--bg); color: var(--ink);
  /* --border-interactive, not --hairline: this is the control's only boundary,
     and WCAG 1.4.11 wants 3:1 there (same rule as the chips and inputs). */
  border: 1px solid var(--border-interactive); border-radius: 12px;
  font: inherit;
  transition: background 200ms ease, border-color 200ms ease;
}
.ask-starter:hover { background: var(--bg-hover); border-color: var(--ink); }
.ask-starter-tag {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  text-transform: var(--label-case, uppercase); color: var(--ink-secondary);
}
.ask-starter-q { font-size: 14.5px; line-height: 1.4; }
/* The arrow answers "what happens if I press this" — it slides in on hover
   and is decorative (the button's text is the label). */
.ask-starter::after {
  content: "→"; position: absolute; right: 14px; bottom: 13px;
  color: var(--ink-secondary); font-size: 14px;
  opacity: 0; transform: translateX(-4px);
  transition: opacity 200ms ease, transform 200ms var(--ease-out);
}
.ask-starter:hover::after, .ask-starter:focus-visible::after { opacity: 1; transform: none; }

/* Composer — one field, focus ring on the wrapper so the textarea can drop
   its own border and the row reads as a single control. */
.ask-foot { padding: 14px; border-top: 1px solid var(--hairline); background: var(--bg); }
.ask-composer {
  display: flex; align-items: flex-end; gap: 8px;
  padding: 5px 5px 5px 16px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-interactive); border-radius: 16px;
  transition: border-color 200ms ease;
}
.ask-composer:focus-within { border-color: var(--ink); outline: 2px solid var(--ink); outline-offset: 1px; }
.ask-composer textarea {
  flex: 1; resize: none; min-height: 40px; max-height: 168px;
  padding: 10px 0; border: 0; background: transparent; color: var(--ink);
  font: inherit; font-size: 15px; line-height: 1.5;
}
.ask-composer textarea:focus { outline: none; } /* the wrapper carries the ring */
.ask-send {
  flex: none; width: 40px; height: 40px; border: 0; border-radius: 999px; cursor: pointer;
  display: grid; place-items: center;
  background: var(--ink); color: var(--bg);
  transition: opacity 200ms ease, transform 200ms var(--ease-out);
}
.ask-send:hover:not(:disabled) { transform: translateY(-1px); }
.ask-send:disabled { opacity: 0.32; cursor: default; }

.ask-hint { display: none; }
@media (hover: hover) and (pointer: fine) {
  .ask-hint {
    display: block; padding: 8px 4px 0; text-align: right;
    font-family: var(--mono); font-size: 10px; letter-spacing: 0.05em;
    color: var(--ink-secondary);
  }
}

/* Legal line — required, but it is fine print, not a paragraph of body copy */
.ask-legal {
  width: min(880px, 100%); margin: 14px 0 0;
  font-family: var(--mono); font-size: 11px; line-height: 1.7;
  letter-spacing: 0.02em; color: var(--ink-secondary);
}
.ask-legal a { text-decoration: underline; text-underline-offset: 2px; }
.ask-legal a:hover { color: var(--ink); }

/* Short-but-wide viewports — landscape tablet, 13" laptops. What pushes the
   composer under the fold there is the head, not the window: so spend width
   on the title (two lines cost 48px that a 1024px-wide screen has to spare)
   and trim the padding, rather than shrinking the window itself. */
@media (min-width: 641px) and (max-height: 900px) {
  .ask-page { --ask-pad: 96px; --ask-gap: 20px; }
  .chat-app--ask .chat-app-body { min-height: clamp(300px, 42vh, 460px); }
}
@media (min-width: 900px) and (max-height: 820px) {
  .ask-head h1 { max-width: 34ch; }
}
/* Landscape phone. Nothing can put the composer on the first screen there —
   the fixed header, the window head and the composer alone are taller than
   375px — so the goal is only to stop spending that screen on padding and a
   two-line title. Note min-height must drop below the cap too: at 375px tall
   the 300px floor beat a 232px max-height and the cap did nothing. */
@media (min-width: 641px) and (max-height: 560px) {
  .ask-page { --ask-pad: 64px; --ask-gap: 14px; }
  .ask-head h1 { max-width: 34ch; font-size: clamp(26px, 3.2vw, 34px); }
  .chat-app--ask .chat-app-body { min-height: 200px; max-height: 62vh; }
}

@media (max-width: 640px) {
  /* Every pixel of head is a pixel the window loses on a phone — measured on
     a 375×812 device the composer sat ~100px below the fold, so a tap on a
     starter filled a field the visitor could not see. */
  .ask-page { --ask-pad: 80px; --ask-gap: 18px; }
  /* 11px + 18px gaps wrapped "free" onto a second line at 375px */
  .ask-facts { gap: 6px 12px; margin-top: 11px; font-size: 10px; letter-spacing: 0.05em; }
  .ask-empty-lede { font-size: 18px; }
  .chat-app--ask .chat-app-body { min-height: 300px; max-height: 46vh; padding: 18px 16px 20px; }
  /* The short cap exists so the composer clears the fold on the empty state.
     Once there are answers to read, reading wins — :has() flips it back
     without JS (old browsers just keep the shorter box). */
  .chat-app--ask .chat-app-body:has(.chat-msg) { max-height: 62vh; }
  .chat-app--ask .ask-consult { display: flex; justify-content: center; }
  .ask-starters { grid-template-columns: 1fr; }
  .ask-empty { gap: 18px; }
  .ask-foot { padding: 12px; }
}

/* On /ask/ the dots report a live 5-90s request, not a decorative demo:
   reduced-motion keeps them visible (the global animation kill makes them
   static), it must not hide them. */
@media (prefers-reduced-motion: reduce) {
  .chat-app--ask .chat-typing { display: flex; }
  .chat-app--ask .chat-typing[hidden] { display: none; }
}

/* ---- Contacts page ---- */
.contact-cards {
  display: grid; gap: 16px; margin: 40px 0 0;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.contact-card {
  padding: 24px; border: 1px solid var(--hairline); border-radius: 10px;
  background: var(--bg-elevated);
}
.contact-card h2 {
  margin: 0 0 8px; font-family: var(--mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-secondary);
}
.contact-value { margin: 0; font-size: 17px; line-height: 1.5; color: var(--ink); }
.contact-value a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--border-interactive); }
.contact-value a:hover { border-bottom-color: var(--ink); }
.contact-channels { margin: 12px 0 0; display: flex; gap: 16px; }
.contact-link {
  font-size: 14px; color: var(--ink-secondary); text-decoration: none;
  transition: color 150ms ease;
}
.contact-link:hover { color: var(--ink); }
.contact-link .arrow { transition: transform 200ms ease; display: inline-block; }
.contact-link:hover .arrow { transform: translateX(3px); }
.contact-legal {
  margin: 40px 0 0; padding-top: 24px; border-top: 1px solid var(--hairline);
  color: var(--ink-secondary); font-size: 14px;
}
.contact-legal h2 {
  margin: 0 0 8px; font-family: var(--mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase;
}
.contact-legal p { margin: 0 0 4px; }
.contact-cta {
  margin: 48px 0 0; padding: 32px; border-radius: 10px;
  background: var(--bg-hover); display: flex; flex-wrap: wrap;
  align-items: center; justify-content: space-between; gap: 20px;
}
.contact-cta p { margin: 0; max-width: 46ch; }

/* ---- Product landing (/products/…) ---- */
.product-pain {
  margin: 40px 0 0; padding: 28px; border-radius: 10px;
  background: var(--bg-hover);
}
.product-pain h2 { margin: 0 0 10px; font-size: 20px; font-weight: 600; }
.product-pain p { margin: 0; max-width: 62ch; color: var(--ink-secondary); }
.product-h2 { margin: 56px 0 20px; font-size: 24px; font-weight: 600; }
.product-steps {
  list-style: none; counter-reset: step; padding: 0; margin: 0;
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.product-steps li {
  counter-increment: step; padding: 24px;
  border: 1px solid var(--hairline); border-radius: 10px;
  background: var(--bg-elevated);
}
.product-steps li::before {
  content: counter(step, decimal-leading-zero);
  display: block; margin-bottom: 12px;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.08em;
  color: var(--ink-secondary);
}
.product-steps h3 { margin: 0 0 8px; font-size: 16px; font-weight: 600; }
.product-steps p { margin: 0; font-size: 14px; color: var(--ink-secondary); }
.product-features { margin: 0; padding-left: 20px; max-width: 62ch; }
.product-features li { margin-bottom: 10px; }
.product-trust {
  margin: 56px 0 0; padding: 28px; border-radius: 10px;
  border: 1px solid var(--hairline);
}
.product-trust h2 { margin: 0 0 16px; font-size: 20px; font-weight: 600; }
.product-trust p { margin: 0 0 12px; max-width: 66ch; color: var(--ink-secondary); }
.product-trust p:last-child { margin-bottom: 0; }
.product-trust strong { color: var(--ink); }
.product-cta {
  margin: 48px 0 0; padding: 32px; border-radius: 10px;
  background: var(--bg-hover);
  display: flex; flex-wrap: wrap; align-items: center; gap: 20px;
}
.product-cta p { margin: 0; flex: 1 1 320px; max-width: 52ch; }

/* ---------- Product flow diagram (/products/reestr/) ---------- */
/* Stacked by default, one row from 800px. The chevron rotates instead of
   being duplicated, so there is one arrow in the markup, not two. */
/* ONE recessed panel, not three more cards. The three numbered steps sit
   directly above this block and used to look identical to it — same white
   card, same radius, same size — so the diagram read as "steps 4, 5, 6"
   instead of as a drawing of the mechanism. The panel is the frame; the nodes
   inside it carry no box of their own. */
.pflow {
  margin: 28px 0 0; padding: 20px 22px;
  background: var(--bg-hover); border: 1px solid var(--hairline);
  border-radius: 10px;
}
.pflow-track { display: grid; gap: 10px; }
.pflow-node { background: none; border: 0; padding: 0; }
/* The middle node is the product, marked by a rule rather than a border box:
   --border-interactive, not --accent, because the acid accent is reserved for
   chip-scale marks. */
.pflow-node--core { padding-left: 12px; border-left: 2px solid var(--border-interactive); }
.pflow-kicker {
  display: block; margin: 0 0 8px; font-family: var(--mono); font-size: 11px;
  font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-secondary);
}
.pflow-node--core .pflow-kicker { color: var(--ink); text-transform: none; letter-spacing: 0.04em; }
.pflow-node p { margin: 0; font-size: 14px; line-height: 1.55; color: var(--ink-secondary); }
.pflow-node--core p { color: var(--ink); }
.pflow-link { display: flex; align-items: center; justify-content: center; color: var(--ink-secondary); }
.pflow-link svg { transform: rotate(90deg); }
/* 24px, not the 10px that separates the nodes inside the track: on a phone
   the track stacks, so the gate landed right under the "your file" node and
   its 2px rule read as a continuation of that node's own rule. The fork is
   not a fourth step — it is the condition on the third — and the only thing
   saying so is this gap. Keep it at least twice the track gap. */
.pflow-gate {
  margin: 24px 0 0; padding-left: 14px; border-left: 2px solid var(--hairline);
  display: grid; gap: 6px;
}
.pflow-gate p { margin: 0; font-size: 14px; line-height: 1.55; color: var(--ink-secondary); }
/* Both selectors carry .pflow-gate on purpose. Written as bare .pflow-ok /
   .pflow-no they LOSE to `.pflow-gate p` on specificity (class+element beats
   class), and both lines rendered in the same secondary grey — the refusal,
   which is the whole point of the diagram, read as an aside. Measured, not
   guessed: computed colour was rgb(110,108,102) for both. */
.pflow-gate .pflow-ok { color: var(--ink); }
/* The one place on this page where red earns its keep: the product's promise
   is that a mismatch is a STOP, not a warning. 7.5:1 on the panel. */
.pflow-gate .pflow-no { color: var(--danger); }
.pflow figcaption {
  margin: 16px 0 0; padding-top: 12px; border-top: 1px solid var(--hairline);
  font-size: 13px; line-height: 1.5; color: var(--ink-secondary); max-width: 62ch;
}
@media (min-width: 800px) {
  .pflow-track { grid-template-columns: 1fr auto 1fr auto 1fr; gap: 14px; align-items: stretch; }
  .pflow-link svg { transform: none; }
}
/* The hand-off to reestr.am is one of only two actions on that page, and it
   measured 139×22 px at 375 — under the 24 px WCAG 2.5.8 floor and half a
   thumb, sitting right beside a 46 px button. Scoped to .product-cta on
   purpose: .contact-link is also an inline text link inside .contact-channels
   on /contacts/, where a 44 px box would pull that row apart. */
.product-cta .contact-link {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px;
}
