/* ==========================================================================
   site-header.css — the home header, for every non-home page.

   One implementation of the header that used to exist three times: the retired
   `.site-head` bar (content, history, landing templates) and a private copy
   inside voice-v2.css. The markup lives in templates/partials/site-header.html
   and the behaviour in assets/site-header.js; the visual spec is the home
   header (voice.saydi.ai: .landing-header, homepage/index.css).

   Pages that link this file already load ds.css (tokens, .ov-lockup) and their
   own page sheet; this file only adds the header + promo banner. The few
   aliases below are the only local variable names — ds.css owns every colour,
   radius and elevation.
   ========================================================================== */

/* Aliases, not a palette: the rules below were written against voice-v2's local
   names. Values stay in ds.css so the header can never fork the tokens. */
:root{
  --paper:var(--canvas);
  --ink:var(--text);
  --line:var(--border);
  --sans:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;
}

/* ── Reset, scoped to the header ─────────────────────────────────────────────
   The studio and the voice pages ship a global reset (`a{text-decoration:none}`,
   `button{background:none;border:0}`); content/history/landing do not, and the
   header must look the same on all of them. Kept to the header's own subtrees so
   it cannot restyle page content. */
.sticky-top a,.mobile-menu-drawer a{text-decoration:none}
.nav button,.mobile-menu-drawer button,.tb-close{font:inherit;color:inherit;background:none;border:0;cursor:pointer}

/* ── Promo banner (MCP / NoteX / Saydi, rotating) ───────────────────────────
   These rules are the front page's own banner sheet (templates/front-page/
   head.html until 2026-11, now here) so the slot is byte-identical on the home
   page, the pricing page and every content/history/voice page. Only the build
   token on the shared artwork URL was dropped: this is a static asset, and the
   ?v= cache-bust belongs on the page link, not inside a stylesheet. */
.top-banner{position:relative;z-index:20;display:flex;align-items:center;justify-content:center;min-height:52px;padding:6px 16px;color:#fff;overflow:hidden}
/* SaydiVoice's own announcement: the MCP connector, i.e. "voice inside
     ChatGPT and Claude". Keeps the orange launch band (Claude's own mark is
     #d97757, so the gradient reads as "AI assistant" instead of the old API
     launch), and the two platform marks ride inline in the title. */
.top-banner--mcp{background:linear-gradient(90deg,#f97316 0%,#fb923c 50%,#f97316 100%)}
/* White on #f97316/#fb923c is 2.8/2.6:1 — a WCAG fail the banner has always had.
   On dark the same brand orange is deepened instead of re-labelled: white then
   measures 5.18:1 and the yellow "MCP" word 4.81:1. */
:root[data-theme="dark"] .top-banner--mcp{background:linear-gradient(90deg,#b45309 0%,#c2410c 50%,#b45309 100%)}
:root[data-theme="dark"] .top-banner--mcp strong{color:#fff}
/* NoteX and Saydi share one artwork but take different crops and colour grades,
     so the two slides never read as the same ad. NoteX sits on the blurred
     flower band (60%) behind a navy scrim; Saydi sits on the dark stem band
     (100%) behind a coral scrim — which is also why its CTA is a white pill and
     not the MCP slide's near-black one. Each scrim is a soft ribbon behind the
     copy so the artwork still reads at both edges, and the background-color +
     gradient layer underneath is the fallback if the image is blocked or still
     loading. */
.top-banner--notex{background-color:#2c4a7a;background-image:linear-gradient(90deg,rgba(7,18,52,.3) 0%,rgba(8,24,64,.62) 30%,rgba(8,24,64,.62) 70%,rgba(0,110,170,.26) 100%),url("/static/homepage/promo-banner-bg.webp");background-position:center,center 60%;background-repeat:no-repeat,no-repeat;background-size:cover,cover}
/* Saydi: same artwork and the same scrim strength as NoteX (so the vertical
     "wave" streaks show through at the same intensity), but a different band and
     grade. Measured across the image, wave energy peaks at Y=45-55% and Y=50% is
     also the warmest slice (mean hue 35°, 61% warm pixels) — the best match for
     Saydi's coral identity, and a different band from NoteX's cooler Y=60%.
     The grade is terracotta rather than the navy NoteX uses. */
.top-banner--saydi{background-color:#5a2416;background-image:linear-gradient(90deg,rgba(46,16,8,.38) 0%,rgba(70,26,16,.66) 26%,rgba(70,26,16,.66) 74%,rgba(150,80,44,.36) 100%),url("/static/homepage/promo-banner-bg.webp");background-position:center,center 50%;background-repeat:no-repeat,no-repeat;background-size:cover,cover}
.top-banner__inner{position:relative;display:flex;align-items:center;justify-content:center;width:100%;max-width:1240px;min-height:40px;padding:0 120px;text-align:center}
.top-banner__boombox,.top-banner__covers{position:absolute;top:50%;height:44px;width:auto;transform:translateY(-50%);pointer-events:none;user-select:none}
.top-banner__boombox{left:0}
.top-banner__covers{right:0}
.top-banner__content{display:flex;align-items:center;justify-content:center;gap:18px;min-width:0}
.top-banner__title{margin:0;font-size:16px;line-height:1.2;font-weight:500;white-space:nowrap;display:inline-flex;align-items:center;gap:8px}
.top-banner__title strong{margin-left:0;font-weight:800;color:#fde047}
/* Product mark, inline with the name so it survives the phone breakpoint where
     the API slide's edge artwork is hidden. Decorative: the name next to it
     already says NoteX / Saydi, hence alt="" + aria-hidden in the markup. */
.top-banner__logo{width:26px;height:26px;flex:none;border-radius:8px;object-fit:cover;box-shadow:0 0 0 1px rgba(255,255,255,.28)}
/* ChatGPT + Claude marks on the MCP slide, inline in the title like the NoteX /
     Saydi product marks above, so they survive the phone breakpoint where the
     edge artwork is hidden. They read as the two tiles the account menu uses,
     but a size up (24px against the menu's 18px) so they hold their shape at
     banner scale. The white ring does two jobs: it separates the overlapping
     pair, and it keeps Claude's #d97757 tile from dissolving into the orange
     band behind it. Decoration only — the copy beside them already says
     "MCP · ChatGPT · Claude", hence aria-hidden in the markup. */
.top-banner__ai-duo{display:inline-flex;flex:none;align-items:center;color:#fff}
.top-banner__ai-tile{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:9px;box-shadow:0 0 0 2px #fff}
.top-banner__ai-tile+.top-banner__ai-tile{margin-left:-7px}
.top-banner__ai-tile svg{width:18px;height:18px}
.top-banner__ai-tile--chatgpt{background:#0d0d0d}
.top-banner__ai-tile--claude{background:#c15f3c}
/* Each product's accent word takes its own logo hue (NoteX blue, Saydi coral),
     tinted light enough to stay readable on that slide's dark backdrop — the
     saturated logo colour itself would sit at ~2:1 there. */
.top-banner--notex .top-banner__title strong{color:#b8dbff}
.top-banner--saydi .top-banner__title strong{color:#ffc49b}
.top-banner__subtitle{color:rgba(255,255,255,.95);font-size:14px;line-height:1.35}
/* One CTA treatment for all three slides, matching the API banner: dark pill,
     white label, light hairline ring. The two artwork slides have a darker,
     lower-contrast backdrop than the MCP slide's orange, so their scrims are
     kept mid-tone and the ring is strong enough to define the button edge
     there (measured pill-vs-backdrop ≥3:1 on all three). */
.top-banner__cta{display:inline-flex;align-items:center;justify-content:center;padding:8px 16px;border-radius:999px;background:var(--black);color:#fff;font-size:13px;font-weight:700;text-decoration:none;white-space:nowrap;box-shadow:inset 0 0 0 1px rgba(255,255,255,.4);transition:background .18s ease}
.top-banner__cta:hover{background:var(--black)}
.top-banner__cta-arrow{display:inline-block;margin-left:4px;transition:transform .18s ease}
.top-banner__cta:hover .top-banner__cta-arrow{transform:translateX(3px)}
/* Both slides share one grid cell, so the row is as tall as the taller slide
     and the swap is a plain cross-fade with no layout shift. The idle slide is
     visibility:hidden, which also keeps its CTA out of the tab order and out of
     the accessibility tree; rotation pauses on hover and on focus. */
.top-banner-rotator{display:grid}
.top-banner-rotator>.top-banner{grid-area:1/1;opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .45s ease,transform .45s ease,visibility 0s linear .45s}
.top-banner-rotator>.top-banner.is-active{opacity:1;visibility:visible;transform:none;transition:opacity .45s ease,transform .45s ease,visibility 0s}
@media (prefers-reduced-motion:reduce){.top-banner-rotator>.top-banner{transform:none;transition:none}}
@media (max-width:1100px){.top-banner__inner{padding:0 92px}.top-banner__boombox,.top-banner__covers{height:38px}}
/* Narrow screens. Both artworks used to be switched off here, which left the MCP
     slide as a bare orange strip while the NoteX/Saydi slides still showed their
     full-bleed artwork. The pair cannot simply be re-scaled either: at 390px they
     measure ~270px together and the title + CTA need ~230px, so this slide
     re-composes instead of shrinking. Both artworks leave the flex flow, so the
     row keeps its full width and one line in every locale:
     · the covers keep their native aspect (object-fit:contain — no squashed or
       half-cropped albums) pinned to the right edge, with their flat orange
       backdrop dissolved into the slide's gradient by a mask instead of ending in
       the hard rectangle edge the desktop crop has;
     · a scrim over them holds the copy at the contrast it has on the plain
       gradient, and the content sits above it;
     · the 36px boombox mark keeps leading the row here, faded out towards the
       middle by a second mask, as long as the copy leaves it room (see 520px). */
@media (max-width:760px){.top-banner{padding:4px 10px}.top-banner__inner{position:static;min-height:44px;padding:0}.top-banner__covers{right:0;top:0;width:100%;height:100%;transform:none;object-fit:contain;object-position:right center;z-index:0;-webkit-mask-image:linear-gradient(90deg,transparent 0%,#000 52%);mask-image:linear-gradient(90deg,transparent 0%,#000 52%);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.top-banner--mcp .top-banner__inner::before{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(90deg,rgba(249,115,22,.62) 0%,rgba(249,115,22,.93) 22%,rgba(249,115,22,.93) 62%,rgba(251,146,60,.18) 100%)}.top-banner__boombox{left:0;top:50%;height:36px;width:auto;z-index:2;-webkit-mask-image:linear-gradient(90deg,#000 0%,#000 68%,transparent 100%);mask-image:linear-gradient(90deg,#000 0%,#000 68%,transparent 100%);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.top-banner__content{position:relative;z-index:2;flex-wrap:wrap;gap:6px 12px}.top-banner__subtitle{font-size:13px}}
/* The MCP slide also drops its subtitle from here: with the covers behind
     and the mark beside the copy, the row has no room left for it — measured
     against the built page the extra line pushes the CTA onto a second one at
     600px in 20 of 32 locales and still at 700px in fil/uk/hu/bg, and a wrapped
     CTA grows the rotator slot past the 52px the other two slides use. The
     NoteX/Saydi slides keep their body copy down to 520px, where the rule below
     drops it for the whole slot. */
@media (max-width:760px){.top-banner--mcp .top-banner__subtitle{display:none}}
/* On phones the mark is dropped again. It is only decoration next to a wordmark
     that already names the product, and the row is genuinely out of space: at
     390px the longest CTA ("MCP verbinden", "MCP ஐ இணைக்கவும்") reaches to within ~40px of the left edge, so the mark would sit
     under the first letters of the title. Measured with it in the row, it also
     tipped the CTA onto a second line at 390px in 22 of the 32 locales. */
@media (max-width:520px){.top-banner__boombox{display:none}.top-banner__subtitle{display:none}.top-banner__title{font-size:14px}.top-banner__cta{padding:7px 12px;font-size:12px}/* The platform pair also steps down with the title, otherwise two 28px tiles
     next to 14px type read as the message and the words as the caption. */
     .top-banner__ai-tile{width:24px;height:24px;border-radius:8px}.top-banner__ai-tile+.top-banner__ai-tile{margin-left:-6px}.top-banner__ai-tile svg{width:15px;height:15px}}
/* 380-420px: the platform pair eats ~40px the row used to have for the wordmark,
     so the savings come out of the decoration and the gaps instead of a wrapped
     CTA — a second line grows the slot past the 52px every other slide uses, and
     the slot changes height on every rotation. Worst of the 32 locales here is
     hu ("MCP csatlakoztatása"), which wrapped at 390px with the arrow still in
     the row. */
@media (max-width:420px){.top-banner__title{font-size:13px}.top-banner__cta-arrow{display:none}.top-banner__content{gap:6px 8px}}
/* Very small phones (320-380px): one more step — smaller title, tighter CTA
     padding, and the pair at 22px. Measured at 320px in the longest locales
     (ta, ru, bg, hu, fil). */
@media (max-width:380px){.top-banner__title{font-size:12px}.top-banner__cta{padding:6px 10px;font-size:11px}.top-banner__ai-tile{width:22px;height:22px}.top-banner__ai-tile svg{width:14px;height:14px}}
/* 320-360px: the last step. Two of the 32 locales (hu, ta) still overflow here
     without it, and a wrapped CTA is the one outcome worth avoiding: it makes
     the slot taller than the NoteX/Saydi slides stacked in the same grid cell. */
@media (max-width:360px){.top-banner__title{font-size:11px}.top-banner__cta{padding:5px 8px;font-size:10px}.top-banner__ai-tile{width:20px;height:20px}.top-banner__ai-tile svg{width:13px;height:13px}.top-banner__content{gap:5px 6px}}

/* The sticky wrapper holds the promo slot + header together, so the header
   stays pinned when the visitor dismisses the slot (7-day memory, see
   assets/site-header.js). The home page has no ✕; content pages do. */
.sticky-top{position:sticky;top:0;z-index:100}
.tb-wrap{position:relative;display:grid;grid-template-rows:1fr;transition:grid-template-rows .3s ease}
.tb-wrap>.top-banner-rotator{min-height:0;overflow:hidden}
.tb-wrap.off{grid-template-rows:0fr}
.tb-wrap[hidden]{display:none}
.tb-close{position:absolute;top:50%;right:12px;z-index:30;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:1px solid transparent;border-radius:999px;overflow:clip;color:#fff;background:transparent;transition:background-color .1s,opacity .2s}
.tb-close:hover{background:rgba(255,255,255,.16)}
.tb-close:active{background:rgba(255,255,255,.24)}
.tb-close:focus-visible{outline:none;background:rgba(255,255,255,.16);box-shadow:0 0 0 2px rgba(0,0,0,.25),0 0 0 4px #fff}
.tb-close svg{width:16px;height:16px}
.tb-wrap.off .tb-close{opacity:0;pointer-events:none}
/* The 40px right inset is for the ✕, and only content pages render it. Scoped to
   the wrapper that actually holds one: on the home page it was stealing 30px of
   the promo row, which is exactly what the longest banner locales need. */
@media (max-width:760px){.tb-close{right:4px}.tb-wrap:has(>.tb-close) .top-banner{padding-right:40px}}

/* ── Header bar ─────────────────────────────────────────────────────────── */
/* White bar, frosted on scroll — the same appearance as the home header, which
   is transparent over its white page and turns rgba(255,255,255,.72) once the
   visitor scrolls. Content pages sit on a tinted body background, so the bar is
   opaque white at rest instead of transparent: the header must read as the same
   surface on every page, not pick up whatever gradient is behind it. */
.nav{position:relative;z-index:100;display:flex;justify-content:center;width:100%;height:64px;background:var(--surface);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);transition:background .2s,box-shadow .2s}
.nav.scrolled{background:var(--glass-bg-strong);box-shadow:0 1px 2px rgba(16,24,40,.04),0 8px 24px -16px rgba(16,24,40,.24)}
.header-content{position:relative;display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;max-width:1440px;height:100%;min-width:0;padding:0 12px}
@media (min-width:1025px){.header-content{padding:0 24px}}
.header-left{display:flex;align-items:center;gap:8px;min-width:0}
.mobile-menu-toggle{display:none;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;color:var(--text);transition:background .2s,color .2s}
.mobile-menu-toggle:hover{background:rgba(0,0,0,.06);color:var(--text)}.mobile-menu-toggle:active{background:rgba(0,0,0,.1)}
.mobile-menu-toggle svg,.mobile-menu-close svg,.lang-switch-btn>svg{width:20px;height:20px;stroke-width:1.5}
/* Brand: the wordmark image, same element/size as the home header
   (a.brand-name.site-brand > img.brand-logo, 118×20 intrinsic). Home gets these
   values from homepage/index.css; every other page gets them here. */
.site-brand{display:inline-flex;align-items:center;flex:none;text-decoration:none}
.site-brand .brand-logo{display:block;height:20px;width:auto;filter:drop-shadow(0 3px 10px color-mix(in srgb, var(--brand-coral) 30%, transparent));transition:transform .18s,filter .18s}
.site-brand:hover .brand-logo{transform:translateY(-1px) rotate(-4deg);filter:drop-shadow(0 6px 16px color-mix(in srgb, var(--brand-coral) 48%, transparent))}
.producthunt-badge{display:inline-flex;align-items:center;margin-left:4px;opacity:.85;transition:opacity .2s}
.producthunt-badge:hover{opacity:1}.producthunt-badge svg{height:40px;width:auto}
.header-center{display:flex;align-items:center;justify-content:center;gap:12px;min-width:0;padding:0 24px}
.nav-menu{display:flex;align-items:center;justify-content:center;gap:2px}
.nav-item-wrap{position:relative;display:inline-flex}
.nav-item{display:inline-flex;align-items:center;gap:4px;height:36px;padding:0 16px;border-radius:999px;font-size:15px;font-weight:500;line-height:18px;color:var(--text);white-space:nowrap;cursor:pointer;transition:background .15s ease}
.nav-item:hover,.nav-item-wrap:hover .nav-item,.nav-item-wrap:focus-within .nav-item{background:var(--surface-hover)}
.nav-item svg{width:12px;height:12px;transition:transform .2s}
.nav-dropdown:hover .nav-item svg,.nav-dropdown:focus-within .nav-item svg{transform:rotate(180deg)}
.nav-dropdown-menu{display:none;position:absolute;top:100%;left:50%;transform:translateX(-50%);z-index:1000;min-width:max-content;padding:8px 0;background:var(--surface);border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,.15)}
.nav-dropdown-menu::before{content:"";position:absolute;left:0;right:0;top:-8px;height:8px}
.nav-dropdown:hover .nav-dropdown-menu,.nav-dropdown:focus-within .nav-dropdown-menu{display:block}
.nav-dropdown-item{display:block;padding:10px 16px;font-size:14px;color:var(--text);white-space:nowrap}
.nav-dropdown-item:hover,.nav-dropdown-item:focus-visible{background:var(--surface-hover)}
@media (max-width:1239.5px){.nav-item{font-size:14px;padding:0 12px}}
.header-actions{display:flex;align-items:center;gap:8px;min-width:0}
/* Appearance button (spec 007). One control, three states; theme.js owns the
   state and the icon swap, so every colour here is a token. */
.sh-theme-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;flex:none;
  border-radius:20px;color:var(--text-2);transition:background .18s,color .18s}
.sh-theme-btn:hover{background:var(--surface-hover);color:var(--text)}
.sh-theme-btn:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.sh-theme-ic{display:none;width:17px;height:17px}
.sh-theme-ic svg{width:17px;height:17px;display:block}
.sh-theme-btn[data-theme-current="light"] [data-theme-icon="light"],
.sh-theme-btn[data-theme-current="dark"] [data-theme-icon="dark"],
.sh-theme-btn[data-theme-current="system"] [data-theme-icon="system"]{display:block}
.lang-dropdown-wrapper{position:relative}
.lang-switch-btn{display:flex;align-items:center;gap:6px;height:30px;padding:4px 10px;border-radius:20px;font-size:14px;font-weight:500;color:var(--text);transition:background .2s}
.lang-switch-btn:hover,.lang-switch-btn[aria-expanded=true]{background:var(--surface-hover)}
.lang-switch-btn .cv{width:12px;height:12px}
.lang-dropdown-panel{position:absolute;right:0;top:100%;z-index:100;display:none;min-width:180px;max-height:320px;overflow-y:auto;margin-top:8px;padding:8px;background:var(--surface);border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,.12)}
.lang-dropdown-panel.on{display:block}
.lang-dropdown-panel a{display:block;padding:8px 12px;border-radius:8px;font-size:14px;color:var(--text)}
.lang-dropdown-panel a+a{margin-top:3px}
.lang-dropdown-panel a:not(.lang-active):hover{background:var(--surface-hover)}
.lang-dropdown-panel a.lang-active{background:var(--accent-soft);color:var(--accent);font-weight:600}
.fp-auth-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;flex:none;height:38px;padding:0 14px;border-radius:999px;border:1px solid #e4e4e7;background:var(--surface);color:#18181b;font-size:14px;font-weight:600;white-space:nowrap}
.fp-auth-btn:hover{background:var(--surface-hover)}
.fp-auth-btn svg{width:16px;height:16px;flex:none;color:var(--text-2)}
/* Signed-in state — home-auth.js swaps the button's contents for the account
   avatar as soon as Firebase reports a session, so these rules must live here,
   in the header's own stylesheet, not in the lazily-loaded auth.css: on pages
   that ship auth.js themselves the bundle CSS arrived (if at all) after the
   avatar had painted, and the <img> rendered at its natural size on top of the
   header (2026-11-07, /vi/history/). Copies in assets/auth.css stay for the
   studio/modal surfaces. */
.fp-auth-btn.fp-auth-signed-in{width:38px;padding:0;justify-content:center;overflow:hidden;border-color:transparent;background:none}
.fp-auth-av{width:30px;height:30px;border-radius:999px;object-fit:cover;display:block}
.fp-auth-initial{display:flex;align-items:center;justify-content:center;background:#18181b;color:#fff;font-size:13px;font-weight:700}
.open-studio-btn{display:inline-flex;align-items:center;justify-content:center;flex:none;height:36px;padding:0 20px;border-radius:var(--r-full);background:var(--accent);color:#fff;font-size:14px;font-weight:600;white-space:nowrap;text-decoration:none;box-shadow:0 4px 14px color-mix(in srgb, var(--accent) 30%, transparent);transition:background .2s,transform .15s,box-shadow .2s}
.open-studio-btn:hover{background:var(--accent-hover);opacity:.9;transform:translateY(-1px);box-shadow:0 6px 20px color-mix(in srgb, var(--accent) 38%, transparent)}

/* ── Mobile drawer ──────────────────────────────────────────────────────── */
.mobile-menu-overlay{position:fixed;inset:0;z-index:200;background:rgba(0,0,0,.4);opacity:0;pointer-events:none;transition:opacity .3s}
.mobile-menu-drawer{position:fixed;top:0;left:0;z-index:201;width:min(100%,360px);height:100dvh;overflow-y:auto;padding:24px 0;background:var(--surface);transform:translateX(-100%);transition:transform .3s ease;visibility:hidden}
body.menu-open .mobile-menu-overlay{opacity:1;pointer-events:auto}
body.menu-open .mobile-menu-drawer{transform:none;visibility:visible}
.mobile-menu-header{display:flex;align-items:center;justify-content:space-between;padding:0 20px 20px;border-bottom:1px solid #f0f0f0}
.mobile-brand-link{font-size:18px;font-weight:800;letter-spacing:-.03em;color:var(--accent);text-decoration:none}
.mobile-menu-close{display:inline-flex;align-items:center;justify-content:center;padding:4px;border-radius:8px;color:var(--text);transition:background .2s,color .2s}
.mobile-menu-close:hover{background:rgba(0,0,0,.06);color:var(--text)}
.mobile-menu-nav{display:flex;flex-direction:column;padding:16px 0}
.mobile-menu-nav a,.mobile-nav-dropdown-header{display:flex;align-items:center;justify-content:space-between;width:100%;padding:12px 20px;font-size:15px;font-weight:600;color:var(--text);text-align:left;text-decoration:none;transition:background .15s}
.mobile-menu-nav a:hover,.mobile-nav-dropdown-header:hover{background:var(--surface-hover)}
.mobile-nav-dropdown-header svg{width:12px;height:12px;transition:transform .2s}
.mobile-nav-dropdown.open .mobile-nav-dropdown-header svg{transform:rotate(180deg)}
.mobile-nav-dropdown-content{display:none;padding-left:16px}
.mobile-nav-dropdown.open .mobile-nav-dropdown-content{display:block}
.mobile-nav-dropdown-content a{font-weight:500}
.mobile-menu-cta{padding:0 20px}
.mobile-nav-studio{display:block;padding:12px;border-radius:var(--r-full);background:var(--accent);color:#fff;font-size:15px;font-weight:600;text-align:center;text-decoration:none}

/* Breakpoints follow the home header: PH badge goes first (≤1240), then the
   centre nav collapses into the burger (≤1024). Below 767.5 the header keeps
   the same four things home keeps — burger, brand, language, sign-in, Studio —
   only tighter; the brand stays LEFT (it used to be re-centred by a duplicate
   .logo-wrapper, which is gone now that the header has one brand element). */
@media (max-width:1240px){.producthunt-badge{display:none}}
@media (max-width:1024px){.nav-menu{display:none}.mobile-menu-toggle{display:flex}.lang-switch-btn{padding:4px 8px}}
@media (max-width:767.5px){
  /* Sizes measured off the home header at 390px: burger 34×40 (22px glyph),
     language pill 28px tall, sign-in 38px circle, Studio pill 32px tall. */
  .header-actions{gap:4px}
  .mobile-menu-toggle{width:34px;height:40px}
  .mobile-menu-toggle svg{width:22px;height:22px}
  .fp-auth-label{display:none}
  .fp-auth-btn{width:38px;padding:0}
  .lang-switch-btn{height:28px;padding:4px 8px;font-size:14px}
  .open-studio-btn{height:32px;padding:0 16px;font-size:13px}
  .site-brand .brand-logo{height:18px}
}
@media (max-width:420px){
  .header-content{padding:0 10px;gap:6px}
  .open-studio-btn{padding:0 14px;font-size:12px}
}
/* Dưới ~390px bốn khối (burger · brand · ngôn ngữ · đăng nhập · Studio) không còn
   vừa: ở 360px hàng header rộng 371px và đẩy cả trang cuộn ngang 11px (32px ở
   320px) — admin console/Android phổ thông gặp đúng khổ này. Thu mỗi khối vài px
   thay vì bỏ bớt một khối; 390px trở lên giữ nguyên như trước. */
@media (max-width:380px){
  .header-content{padding:0 8px;gap:4px}
  .header-actions{gap:2px}
  .site-brand .brand-logo{height:16px}
  .lang-switch-btn{padding:4px 6px;gap:4px}
  .open-studio-btn{padding:0 10px;font-size:12px}
}
/* 320–340px (iPhone SE 1 / Android nhỏ): bỏ mũi tên của pill ngôn ngữ và thu nút
   đăng nhập; vẫn giữ đủ 5 khối nhưng trang không còn cuộn ngang. */
@media (max-width:340px){
  .header-content{gap:2px}
  .lang-switch-btn .cv{display:none}
  .lang-switch-btn{padding:4px 5px}
  .open-studio-btn{padding:0 4px;font-size:11px}
  .site-brand .brand-logo{height:14px}
}