/* ============================================================================
   Hayotiy Til — design system
   Ported from the approved til.uz direction 2a (Claude Design): Onest for UI,
   Literata for editorial headings, warm paper ground, single red accent.

   Accessibility targets follow TZ 4.1.6 (WCAG 2.1 AA): contrast, 44px touch
   targets, visible focus, keyboard navigation, and layout that survives 200%
   browser zoom because every size is in rem/em or clamp().
   ========================================================================= */

:root {
  /* ground & ink */
  --paper:        #FAF6EF;
  --paper-alt:    #F3ECDF;
  --paper-warm:   #EFE7DA;
  --white:        #ffffff;
  --ink:          #2C2622;
  --ink-soft:     #4A4038;
  --muted:        #5E5346;   /* AA on --paper */
  --faint:        #6E6355;   /* AA on --paper */
  --line:         #E7DDD0;
  --line-strong:  #E0D6C8;
  --sand:         #C9BBA8;

  /* accent */
  --accent:       #FB493B;
  --accent-deep:  #A83A2C;   /* AA on --paper for small text */
  --accent-wash:  #FBEEE9;

  /* semantic */
  --ok:           #1E7D48;
  --warn:         #8A6A1F;

  --radius-sm: 8px;
  --radius:    12px;
  --radius-lg: 16px;
  --shadow-sm: 0 1px 3px rgba(76, 54, 32, .06);
  --shadow:    0 10px 30px rgba(76, 54, 32, .08);
  --shadow-lg: 0 12px 32px rgba(76, 54, 32, .10);

  --wrap: 1160px;
  --font-ui: Onest, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-serif: Literata, Georgia, "Noto Serif", "Times New Roman", serif;
}

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

a { color: var(--accent-deep); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

img { max-width: 100%; height: auto; }

h1, h2, h3, h4 {
  font-family: var(--font-serif);
  font-weight: 600;
  line-height: 1.2;
  margin: 0 0 .5em;
  letter-spacing: -.01em;
  text-wrap: balance;
}
h1 { font-size: clamp(1.75rem, 4vw, 2.6rem); font-weight: 500; }
h2 { font-size: clamp(1.35rem, 2.6vw, 1.875rem); }
h3 { font-size: clamp(1.1rem, 2vw, 1.3rem); }
p  { margin: 0 0 1em; text-wrap: pretty; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 1.5rem; }
.wrap--narrow { max-width: 800px; }
.wrap--reading { max-width: 720px; }

/* skip link — keyboard navigation, TZ 4.1.6 */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--ink); color: var(--paper);
  padding: .75rem 1.25rem; border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; }

/* ---------------------------------------------------------------- top strip */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding: .5rem 0;
  border-bottom: 1px solid var(--line);
  font-size: .78rem;
  color: var(--muted);
}
.topbar__links { display: flex; align-items: center; gap: 1.125rem; flex-wrap: wrap; }
.topbar a { color: var(--muted); }

/* Script switcher (TZ 4.1.2 — must stay permanently reachable). Rendered
   twice: the wide copy sits in the top strip as the approved 2a artboard
   shows, the narrow copy in the brand row on phones. Exactly one is ever
   displayed, so only one reaches the accessibility tree. */
.script-switch { display: inline-flex; align-items: center; gap: .75rem; }
.topbar__links .script-switch { margin-left: .5rem; }
.script-switch a {
  padding: .25rem 0; color: var(--muted); font-size: .82rem;
  line-height: 1.5; text-decoration: none; min-height: 30px;
  display: inline-flex; align-items: center;
  border-bottom: 2px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.script-switch a:hover {
  text-decoration: none; color: var(--ink); border-bottom-color: var(--line-strong);
}
/* The current script is marked by an underline rather than a filled pill —
   the control reads as a pair of links, which is what it is. */
.script-switch a[aria-current="true"] {
  color: var(--ink); font-weight: 600; border-bottom-color: var(--accent);
}
.script-switch a[aria-current="true"]:hover { border-bottom-color: var(--accent); }
/* The narrow copy is hidden by default and only shown at phone widths; this
   must sit AFTER the base .script-switch rule to win on source order. */
.script-switch--narrow { display: none; }

/* -------------------------------------------------------------------- header */
.masthead { border-bottom: 1px solid var(--line); background: var(--paper); }
.masthead__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; padding: 1rem 0;
}
.brand { display: inline-flex; align-items: center; gap: .8rem; }
.brand img { width: 36px; height: 33px; flex: none; }
.brand__word {
  display: block; font-weight: 800; font-size: 1.6rem;
  letter-spacing: -.02em; line-height: 1; color: var(--ink);
}
.brand__word span { color: var(--accent); }
.brand__sub { display: block; font-size: .72rem; color: var(--muted); margin-top: .2rem; }
.brand:hover { text-decoration: none; }

.nav { display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap;
       margin-left: auto; }
.nav a {
  color: var(--ink); font-size: .95rem; font-weight: 500;
  padding: .5rem 0; min-height: 44px; display: inline-flex; align-items: center;
}
.nav a[aria-current="page"] { box-shadow: inset 0 -2px 0 var(--accent); }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border: 1px solid var(--line-strong);
  border-radius: 99px; color: var(--ink); background: transparent;
}
.icon-btn:hover { text-decoration: none; border-color: var(--sand); }

.nav-toggle { display: none; }

/* --------------------------------------------------------------- components */
.eyebrow {
  font-size: .72rem; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 700; color: var(--accent-deep); margin: 0 0 .5rem;
}

/* The name of a source, wherever one is credited. A dictionary title is a
   proper name and reads as one — the uppercase treatment of .eyebrow turns a
   50-character title into shouting.

   Link-coloured, so it is legible as the way through to the dictionary, but
   kept light and unadorned: it sits between a headword and a definition and
   should not compete with either. */
.source-name {
  font-size: .8125rem; font-weight: 400; letter-spacing: 0;
  color: var(--accent-deep); text-transform: none; margin: 0;
  text-decoration: none;
}
a.source-name:hover, a.source-name:focus-visible { color: var(--accent); }

.section-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; border-bottom: 2px solid var(--ink);
  padding-bottom: .625rem; margin: 0 0 1.375rem;
}
.section-head h2 { margin: 0; }
.section-head a { font-size: .875rem; font-weight: 500; }

.card {
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.25rem 1.375rem;
  box-shadow: var(--shadow-sm);
}
.card--flat { box-shadow: none; }
.card--dark { background: var(--ink); color: #F3EADD; border-color: var(--ink); }
.card--dark a { color: #F3EADD; }

.grid { display: grid; gap: 1.125rem; }
/* Without this a single wide child (a map, a table, a long word)
   sets a min-content floor and pushes the whole grid off screen. */
.grid > * { min-width: 0; }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.grid--cards { grid-template-columns: repeat(4, 1fr); }
.grid--sidebar { grid-template-columns: 1.55fr 1fr; }

.pill {
  display: inline-flex; align-items: center; gap: .35rem;
  background: var(--white); border: 1px solid var(--line-strong);
  border-radius: 99px; padding: .3rem .8rem; font-size: .8rem;
  color: var(--ink); text-decoration: none; min-height: 32px;
}
.pill:hover { text-decoration: none; border-color: var(--sand); }
.pill[aria-pressed="true"], .pill--active {
  background: var(--ink); color: var(--paper); border-color: var(--ink);
}

.badge {
  display: inline-block; font-size: .68rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  border-radius: 99px; padding: .2rem .625rem;
  background: var(--accent-wash); color: var(--accent-deep);
}
.badge--muted { background: var(--paper-warm); color: var(--faint); }
/* A language tag sits beside a headword several times its size. Its row is
   baseline-aligned — the Cyrillic pair beside the heading needs that — but a
   pill has a box, and putting its small text on the heading's baseline drops
   the box well below the word's middle. It centres on the text instead:
   align-self where the row is flex, vertical-align where it is inline. */
.badge--lang { align-self: center; vertical-align: middle; }

/* Sources capitalise headwords however they please — mehr, MEHR, Меҳр, love²,
   SALOMNOMA — so a page of results reads as though the case meant something.
   It does not, so it is set once here rather than edited into 263 000 rows. */
.headword { text-transform: uppercase; }
.badge--ok { background: #E8F3EC; color: var(--ok); }
.badge--warn { background: #F6EFDC; color: var(--warn); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font-family: var(--font-ui); font-weight: 600; font-size: .95rem;
  padding: .75rem 1.375rem; border-radius: 9px; border: 1px solid transparent;
  cursor: pointer; min-height: 44px; text-decoration: none;
}
.btn:hover { text-decoration: none; }
.btn--primary { background: var(--accent); color: var(--white); }
.btn--primary:hover { background: #E23B2E; }
.btn--ghost { border-color: var(--sand); background: transparent; color: var(--ink); }
.btn--ghost:hover { border-color: var(--ink); }
.btn--sm { padding: .5rem 1rem; min-height: 38px; font-size: .875rem; }

/* search box (the 2a hero input group) */
/* The hero stagger animates siblings with fill-mode: both, which keeps each of
   them in a stacking context for good — so the decorative rule *after* the form
   painted over the open dropdown. The form has to win that comparison itself;
   a z-index on the panel inside it is trapped and cannot. */
.searchbox { position: relative; z-index: 30; }
.searchbox__field { position: relative; }
.hero-decor { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.searchbox__group {
  display: flex; background: var(--white); border: 1px solid var(--line-strong);
  border-radius: 14px; box-shadow: var(--shadow);
  transition: border-radius .12s ease;
}
.searchbox input[type="search"], .searchbox input[type="text"] {
  flex: 1; border: 0; outline: 0; background: transparent;
  padding: 1rem .5rem 1rem 1.25rem; font-size: 1.0625rem;
  font-family: var(--font-ui); color: var(--ink); min-width: 0;
}
.searchbox input[type="search"]::-webkit-search-cancel-button { display: none; }
.searchbox__submit { margin: .5rem; border-radius: 9px; }
.searchbox__submit-icon { display: none; }
/* The back arrow only exists in the mobile overlay below. */
.searchbox__back {
  display: none; place-items: center; width: 44px; flex: 0 0 44px;
  border: 0; background: none; color: var(--muted); cursor: pointer;
  padding: 0; margin-left: .25rem; border-radius: 50%;
}
.searchbox__back:hover, .searchbox__back:focus-visible { color: var(--ink); }

/* The panel is joined to the input rather than floating below it: the two
   share an edge, so the list reads as an extension of the field. */
.suggestions {
  position: absolute; left: 0; right: 0; top: 100%;
  background: var(--white); border: 1px solid var(--line-strong);
  border-top: 0; border-radius: 0 0 14px 14px;
  box-shadow: var(--shadow-lg);
  list-style: none; margin: 0; padding: .25rem; text-align: left;
  max-height: min(58vh, 24rem); overflow-y: auto;
  overscroll-behavior: contain;
}
.searchbox.is-suggesting .searchbox__group {
  border-radius: 14px 14px 0 0; box-shadow: none;
}
.suggestions li { margin: 0; }
.suggestions button {
  display: block; width: 100%; text-align: left; background: none; border: 0;
  padding: .75rem .875rem; font: inherit; color: var(--ink);
  border-radius: var(--radius-sm); cursor: pointer;
}
.suggestions button:hover, .suggestions button:focus { background: var(--paper); }
.suggestions[hidden] { display: none; }

/* What the search understands, shown in the mobile panel while it is still
   empty. It answers the question a blank field invites — what can I type? —
   and costs nothing on the landing page, where it is not rendered. */
.searchbox__help { display: none; padding: 1.125rem 1.25rem 1.5rem; }
.searchbox__help-head {
  margin: 0; font-size: .72rem; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 700; color: var(--faint);
}
.searchbox__help ul {
  list-style: none; margin: .875rem 0 0; padding: 0; display: grid; gap: .75rem;
}
.searchbox__help li {
  margin: 0; font-size: .875rem; line-height: 1.45; color: var(--muted);
}
/* The examples are set apart by colour alone — at this size a bolder weight
   made three short lines look like three headings. */
.searchbox__help b { font-weight: inherit; color: var(--ink); }

/* --- mobile: focusing the field takes over the screen ---------------------
   On a phone the box sits halfway down the page, so an open keyboard leaves
   the list a few cramped lines between hero and keyboard. Focusing gives the
   search the whole viewport, the way a native search does. */

@media (max-width: 640px) {
  body.is-searching { overflow: hidden; }

  /* The whole screen, like a native search screen: while you are searching,
     searching is all there is. Nothing of the page shows through, so there is
     nothing to dim and no way to tap "outside" — the back arrow and Escape are
     the ways out. */
  .searchbox.is-open {
    position: fixed; inset: 0; z-index: 120; overflow-y: auto;
    margin: 0; padding: .5rem .625rem .625rem; background: var(--white);
    animation: search-lift .22s cubic-bezier(.2, .7, .3, 1);
    /* The hero centres its children; the panel is its own context and reads
       as a column of text, so it sets alignment rather than inheriting it. */
    text-align: left;
  }
  .searchbox.is-open .searchbox__group {
    border-radius: var(--radius); border-color: var(--line-strong);
    box-shadow: none;
  }
  .searchbox.is-open .searchbox__back { display: grid; }
  .searchbox.is-open input[type="search"] { padding: .8125rem .5rem; }

  /* The label gives way to the magnifier — the same one the masthead uses.
     At this width the field needs the room, and the icon says enough. */
  .searchbox.is-open .searchbox__submit {
    margin: .3125rem; padding: 0; width: 42px; min-height: 42px;
    display: grid; place-items: center;
  }
  .searchbox.is-open .searchbox__submit-label { position: absolute; left: -9999px; }
  .searchbox.is-open .searchbox__submit-icon { display: block; }

  /* The list stays joined to the field, which is now inset from the edges. */
  .searchbox.is-open .suggestions {
    border-color: var(--line-strong);
    border-radius: 0 0 var(--radius) var(--radius);
    /* Fills what is left above the keyboard instead of a fixed cap. */
    max-height: calc(100dvh - 6rem);
  }
  .searchbox.is-open.is-suggesting .searchbox__group {
    border-radius: var(--radius) var(--radius) 0 0;
  }

  .searchbox.is-open:not(.is-suggesting) .searchbox__help { display: block; }
}

@keyframes search-lift { from { opacity: 0; transform: translateY(-8px); } }

/* --- skeletons -------------------------------------------------------------
   Used only where content really is fetched after the page has painted:
   the autocomplete list and the reader's word popup. Server-rendered pages
   (word cards, search results) arrive complete and must not be faked. */
.skeleton {
  background: linear-gradient(90deg,
              var(--line) 25%, var(--paper-warm) 37%, var(--line) 63%);
  background-size: 400% 100%;
  border-radius: 4px;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
}
@keyframes skeleton-shimmer {
  from { background-position: 100% 50%; }
  to   { background-position: 0 50%; }
}
.suggestions__loading { padding: .5rem .875rem; display: grid; gap: .5rem; }
.suggestions__loading .skeleton { height: 1rem; }
.suggestions__loading .skeleton:nth-child(1) { width: 72%; }
.suggestions__loading .skeleton:nth-child(2) { width: 54%; }
.suggestions__loading .skeleton:nth-child(3) { width: 63%; }

@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; background: var(--line); }
}

/* ornamental divider from the 2a hero */
.rule { display: flex; justify-content: center; align-items: center; gap: .875rem;
        margin: 2rem 0; }
.rule i { flex: 1; max-width: 140px; height: 1px; background: var(--line-strong); }
.rule b { width: 6px; height: 6px; border: 1.2px solid #C9A38F; transform: rotate(45deg); }
.rule em { width: 8px; height: 8px; background: var(--accent); opacity: .75;
           transform: rotate(45deg); }

.band { background: var(--paper-alt); border-block: 1px solid var(--line);
        padding: 3rem 0; margin: 3rem 0; }

.breadcrumbs { font-size: .8rem; color: var(--muted); padding: 1rem 0 0; }
.breadcrumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: .4rem;
                  margin: 0; padding: 0; }
.breadcrumbs li::after { content: "·"; margin-left: .4rem; color: var(--sand); }
.breadcrumbs li:last-child::after { content: ""; }

.prose { font-size: 1.0625rem; line-height: 1.7; }
.prose h2 { margin-top: 2rem; }
.prose h3 { margin-top: 1.5rem; }
.prose ul, .prose ol { padding-left: 1.25rem; }
.prose blockquote {
  margin: 1.5rem 0; padding: .25rem 0 .25rem 1.25rem;
  border-left: 3px solid var(--accent); font-family: var(--font-serif);
  font-style: italic; color: var(--ink-soft);
}
.prose table { width: 100%; border-collapse: collapse; }
.prose td, .prose th { border: 1px solid var(--line); padding: .5rem .75rem;
                       text-align: left; }
.table-scroll { overflow-x: auto; }

.muted { color: var(--muted); }
.faint { color: var(--faint); }
.small { font-size: .8rem; }
.serif { font-family: var(--font-serif); }
.stack > * + * { margin-top: 1rem; }
.cluster { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.center { text-align: center; }
.home-hero { position: relative; padding-top: 4rem; padding-bottom: 1.5rem; }
.home-hero h1 { margin-bottom: .75rem; }
.home-hero__lead { max-width: 30rem; margin-bottom: 1.75rem; }
@media (max-width: 640px) {
  .home-hero { padding-top: 2rem; }
  .home-hero__lead { margin-bottom: 1.5rem; font-size: 1rem; }
}

/* forms */
.field { margin-bottom: 1.125rem; }
.field label { display: block; font-weight: 500; font-size: .9rem;
               margin-bottom: .375rem; }
.field .help { font-size: .8rem; color: var(--muted); margin-top: .25rem; }
.field .errorlist { list-style: none; margin: .375rem 0 0; padding: 0;
                    color: #B3261E; font-size: .85rem; }
input[type="text"], input[type="email"], input[type="search"], input[type="url"],
select, textarea {
  width: 100%; font: inherit; color: var(--ink); background: var(--white);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  padding: .625rem .75rem; min-height: 44px;
}
textarea { min-height: 8rem; resize: vertical; }
.checkbox { display: flex; gap: .625rem; align-items: flex-start; }
.checkbox input { width: 20px; height: 20px; min-height: 0; margin-top: .15rem; }
.checkbox label { font-weight: 400; }

.alert { border-radius: var(--radius); padding: .875rem 1.125rem;
         margin-bottom: 1.25rem; border: 1px solid var(--line-strong);
         background: var(--white); }
.alert--success { background: #E8F3EC; border-color: #BEDFC9; color: #14532D; }
.alert--error { background: #FBE9E7; border-color: #F3C6C0; color: #8B1D13; }
.alert--info { background: var(--paper-alt); }

/* a standing note that a section is not finished (see TZ scope notes) */
.stub-note {
  display: flex; gap: .875rem; align-items: flex-start;
  background: var(--paper-alt); border: 1px dashed var(--sand);
  border-radius: var(--radius); padding: 1rem 1.125rem; margin-bottom: 1.75rem;
  font-size: .9rem; color: var(--ink-soft);
}
.stub-note strong { color: var(--ink); }

.pagination { display: flex; gap: .5rem; justify-content: center;
              align-items: center; margin: 2rem 0; flex-wrap: wrap; }
.pagination a, .pagination span {
  min-width: 44px; min-height: 44px; padding: .5rem .75rem;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--white); color: var(--ink);
}
.pagination .current { background: var(--ink); color: var(--paper);
                       border-color: var(--ink); }

.empty { text-align: center; padding: 3rem 1rem; color: var(--muted); }

/* collapsible filter panel */
.filters__summary {
  cursor: pointer; font-weight: 600; font-size: .95rem;
  list-style: none; display: inline-flex; align-items: center; gap: .5rem;
  min-height: 44px;
}
.filters__summary::-webkit-details-marker { display: none; }
.filters__summary::before {
  content: "›"; transition: transform .15s ease; display: inline-block;
  font-size: 1.2rem; color: var(--muted);
}
.filters__details[open] .filters__summary::before { transform: rotate(90deg); }
.filters__checks { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 1rem; }
.filters__actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }

/* dialect map */
.dialect-map__scroll { overflow-x: auto; }

/* -------------------------------------------------------------------- footer */
.footer { margin-top: auto; background: var(--ink); color: #CFC5B8;
          padding: 2.75rem 0 0; }
.footer a { color: #CFC5B8; }
.footer__grid { display: grid; grid-template-columns: 1.3fr 1fr 1fr 1.3fr;
                gap: 1.875rem; padding-bottom: 1.875rem; }
.footer__title { font-size: .7rem; letter-spacing: .14em; text-transform: uppercase;
                 color: #9A8E7F; font-weight: 700; display: block;
                 margin-bottom: .75rem; }
.footer__list { display: flex; flex-direction: column; gap: .5rem;
                font-size: .875rem; }
.footer__brand { display: flex; align-items: center; gap: .7rem; }
.footer__brand img { width: 26px; height: 24px; }
.footer__word { font-weight: 800; font-size: 1.25rem; color: #fff;
                letter-spacing: -.02em; }
.footer__word span { color: var(--accent); }
.footer__bottom { border-top: 1px solid rgba(255,255,255,.12); }
.footer__bottom .wrap { display: flex; justify-content: space-between;
                        gap: 1rem; flex-wrap: wrap; padding-block: 1rem;
                        font-size: .75rem; color: #9A8E7F; }

/* ------------------------------------------------------------------ responsive */
@media (max-width: 900px) {
  .grid--4, .grid--cards { grid-template-columns: repeat(2, 1fr); }
  .grid--sidebar { grid-template-columns: 1fr; }
  .footer__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; }
  .grid--cards { grid-template-columns: repeat(2, 1fr); gap: .875rem; }
  .footer__grid { grid-template-columns: 1fr; }
  .section-head { flex-direction: column; align-items: flex-start; gap: .25rem; }
  .band { padding: 2rem 0; margin: 2rem 0; }

  /* --- compact header -------------------------------------------------
     On a phone the header was costing ~650px before any content. What
     survives is what a reader actually needs here: identity, the script
     switch (TZ 4.1.2 requires it to stay permanently reachable), search,
     and the four sections. The strapline and the secondary links are cut —
     both are reachable in the footer. */
  /* Nothing in the top strip survives on a phone: the strapline and the
     secondary links both live in the footer, and the switch has moved into
     the brand row. */
  .topbar { display: none; }
  .script-switch--wide { display: none; }
  .script-switch--narrow { display: inline-flex; margin-left: auto;
                           margin-right: .5rem; }
  .script-switch a { min-height: 36px; }

  /* No bottom padding here: the nav row is the last child and owns its own
     symmetric padding, otherwise this padding lands under the links only
     and the row reads as sitting too high in its band. */
  .masthead__inner { padding: .625rem 0 0; gap: .625rem; flex-wrap: wrap; }
  .brand img { width: 30px; height: 27px; }
  .brand__word { font-size: 1.375rem; }
  .brand__sub { font-size: .68rem; }
  .icon-btn { width: 40px; height: 40px; flex: none; }

  .nav {
    order: 3; width: 100%; margin-left: 0; gap: 1.25rem;
    flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    border-top: 1px solid var(--line);
    padding-block: .25rem;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { min-height: 40px; white-space: nowrap; font-size: .9375rem; }

  /* The filter panel was pushing the results a full screen down; on a phone it
     starts collapsed (ui.js) unless a filter is already applied. */
  .filters { padding: .75rem 1rem; }
  .filters__checks { gap: .625rem; flex-direction: column; }
  .filters__actions .btn { flex: 1 1 auto; }

  /* TZ 4.2.3а: on small screens the region list is the navigation, so it comes
     first; the schematic map follows and scrolls sideways rather than shrinking
     its labels into illegibility. */
  .dialect-side { order: -1; }
  .dialect-map__scroll svg { min-width: 30rem; }
  .dialect-map text { font-size: 13px; }
  .dialect-side .footer__list { display: grid;
    grid-template-columns: repeat(2, 1fr); gap: .5rem .75rem; }
}

/* Very small screens still have to work — TZ 4.1.6 sets the floor at 320px. */
@media (max-width: 380px) {
  .wrap { padding: 0 1rem; }
  .brand__sub { display: none; }
  .brand img { width: 26px; height: 24px; }
  .brand__word { font-size: 1.25rem; }
  .script-switch { gap: .625rem; }
  .script-switch a { font-size: .8rem; }
  .icon-btn { width: 36px; height: 36px; }
  .nav { gap: 1rem; }
  .nav a { font-size: .875rem; }
}

/* ===========================================================================
   Motion
   The portal is server-rendered, so navigation is a real document load. Rather
   than simulate routing in JS, same-document continuity comes from the CSS
   View Transitions API: no script, no framework, and browsers without support
   simply navigate as before.
   ======================================================================== */
@view-transition { navigation: auto; }

@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root) { animation: vt-fade-out .16s ease both; }
  ::view-transition-new(root) { animation: vt-fade-in .22s ease both; }

  /* The masthead is visually identical between pages; holding it still stops
     the header appearing to blink on every navigation. */
  .masthead { view-transition-name: masthead; }
  ::view-transition-old(masthead),
  ::view-transition-new(masthead) { animation: none; mix-blend-mode: normal; }

  /* Home hero: a short stagger on first paint. */
  .home-hero > h1, .home-hero > p, .home-hero > form, .home-hero > .rule {
    animation: hero-rise .45s cubic-bezier(.2, .7, .3, 1) both;
  }
  .home-hero > p { animation-delay: .05s; }
  .home-hero > form { animation-delay: .1s; }
  .home-hero > .rule { animation-delay: .15s; }
}

@keyframes vt-fade-out { to { opacity: 0; } }
@keyframes vt-fade-in { from { opacity: 0; transform: translateY(6px); } }
@keyframes hero-rise { from { opacity: 0; transform: translateY(8px); } }

/* Indeterminate navigation bar — see js/progress.js. It is only revealed when
   a navigation actually takes long enough to be worth reporting. */
.navbar-progress {
  position: fixed; inset: 0 auto auto 0; height: 3px; width: 0;
  background: var(--accent); z-index: 200; opacity: 0;
  transition: width .2s ease, opacity .2s ease;
  pointer-events: none;
}
.navbar-progress.is-active { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; transition-duration: .001ms !important;
  }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
  .navbar-progress { transition: none; }
}

@media print {
  .topbar, .nav, .footer, .script-switch, .searchbox { display: none; }
  body { background: #fff; }
}
