/* FaraDars public site — FaraJob design system v3 "Balanced Professional"
   Shared public-site styles and design tokens.
   Near-white warm-gray foundation, white content cards, one equal-weight
   accent family per content category, ONE brand blue for every action
   (search, buttons, links) so brand color = "what you can do" and category
   color = "what you are looking at". Vazirmatn everywhere, short functional
   motion.

   Category color plumbing: templates put the type's whole family on a wrapper
   via the `cat_style` filter (--type-color + --c-dark/-panel/-tile/-wash/-on/
   -border/-chip/-shadow). :root carries the neutral ink/gray family, so
   anything outside a category scope stays neutral. */

@import url('fonts.css');

@counter-style fa-decimal {
  system: numeric;
  symbols: '۰' '۱' '۲' '۳' '۴' '۵' '۶' '۷' '۸' '۹';
  suffix: '. ';
}

:root {
  /* Sticky-bar clearance (F52): the logged-in admin bar publishes its
     measured height here (assets/adminbar.js; 0 for normal visitors — and
     the draft-preview indicator is a pill INSIDE the bar, F53, so this one
     variable covers everything sticky). Every anchor scroll-margin and the
     TOC scroll-spy add it so content never lands underneath the bar. */
  --admin-bar-h: 0px;
  --sticky-bars: var(--admin-bar-h);
  /* neutrals — v3 foundation: near-white warm-gray page, pure-white cards */
  --paper: #faf9f7;
  --surface: #ffffff;
  --sand: #f5f4f1;
  --line: #dedcd7;
  --line-strong: #c9c6c0;
  --line-input: var(--line-strong);
  --line-soft: #eceae6;
  /* inks — primary / body / secondary / subtle */
  --ink: #242321;
  --ink-2: #57544f;
  --ink-3: #66635f;
  --ink-4: #817d77;
  --ink-body: #3f3d39;
  --ink-placeholder: #6d6a65;
  --chev: var(--ink-4);
  /* the site's ONE action color — search, buttons, links, focus. Category
     hues never drive actions; a calm blue reads trustworthy on buttons. */
  --brand: #236ea1;
  --brand-dark: #19577f;
  --brand-ring: rgba(35, 110, 161, 0.16);
  --focus: #0b78c4;
  /* neutral category family (overridden per scope by cat_style) */
  --type-color: #242321;
  --c-dark: #111010;
  --c-panel: #f5f4f1;
  --c-tile: #eceae6;
  --c-wash: #f8f7f4;
  --c-on: #faf9f7;
  --c-border: #dedcd7;
  --c-chip: #cfccc7;
  --c-shadow: rgba(36, 35, 33, 0.1);
}

* { box-sizing: border-box; }

/* F157: ONE typeface everywhere — form controls and buttons do not inherit
   the document font by default, which let UA fonts leak into button labels
   and (via ::after) the injected tooltips. */
button, input, select, textarea { font: inherit; }

html {
  -webkit-text-size-adjust: 100%;
  scrollbar-gutter: stable;
  /* F141: the body backstop alone still let the ROOT scroll horizontally
     when something overflowed — clip here too (clip ≠ hidden: no scroll
     container, sticky descendants unaffected). */
  overflow-x: clip;
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-family: 'Vazirmatn', 'Segoe UI', Tahoma, Arial, sans-serif;
  font-size: 1.03125rem; /* 16.5px */
  line-height: 1.85;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  /* F139: any stray min-content overflow (long LTR tokens, a wide chrome
     element) must never widen the page into a horizontal pan on phones.
     `clip` — not `hidden` — so no scroll container is created and
     position: sticky descendants keep working. */
  overflow-x: clip;
}

/* Code: Vazir Code (fonts.css) pairs Latin code glyphs with real Persian
   forms — the OS monospace Arabic fallback stretches glyphs. */
code, kbd, samp, pre { font-family: 'Vazir Code', ui-monospace, Consolas, monospace; }

::selection { background: #cde4f4; color: var(--ink); }
/* Ellipsis so a placeholder longer than the box fades out as «…» instead of
   hard-clipping mid-word (the hero placeholder at phone widths). */
input::placeholder { color: var(--ink-placeholder); opacity: 1; text-overflow: ellipsis; }

/* No underlines anywhere (they cross Persian descenders); links signal with
   the brand blue and answer hover with the darker step. */
a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-dark); }

/* One consistent, always-visible keyboard focus ring, everywhere. */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* Skip link (base.njk renders it first in <body>): parked above the viewport
   until keyboard focus reveals it; must sit over the admin bar too. */
.skip-link {
  position: fixed;
  inset-block-start: -100px;
  inset-inline-start: 16px;
  z-index: 210;
  padding: 10px 18px;
  border-radius: 12px;
  background: var(--brand);
  color: #fff;
  font-weight: 700;
  transition: none;
}
.skip-link:focus-visible { inset-block-start: calc(var(--sticky-bars) + 8px); outline-offset: 2px; }
/* The skip link moves focus to <main tabindex="-1">; a page-wide focus ring
   around the whole content column is noise, not orientation. */
main:focus { outline: none; }

h1, h2, h3, h4, h5, h6 { line-height: 1.45; color: var(--ink); }
h1 { font-size: 2rem; font-weight: 800; letter-spacing: -0.02em; line-height: 1.45; margin-block: 0.5rem 0.75rem; }
h2 { font-size: 1.375rem; font-weight: 800; margin-block: 0 1rem; }
h3 { font-size: 1.03125rem; font-weight: 800; margin-block: 0 0.5rem; line-height: 1.6; }
/* F99: the h4 tier exists now that the outline is strict (section h2 → field
   h3 → item/content h4) — one visual notch under h3. */
h4 { font-size: 0.97rem; font-weight: 800; margin-block: 0 0.5rem; line-height: 1.6; }
/* Deep-nested authored prose only: shiftHeadings (F99) can push a richtext
   fragment's outline down to h5/h6. One notch under h4, never browser
   defaults. */
h5, h6 { font-size: 0.93rem; font-weight: 800; margin-block: 0 0.5rem; line-height: 1.6; }

p { margin-block: 0 1rem; }

ul, ol { padding-inline-start: 1.5rem; margin-block: 0 1rem; }
li { margin-block-end: 0.35rem; }
ol { list-style-type: fa-decimal; }

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

/* The content column (padding included). Widened from the design's 1040px
   board to use more of the viewport. */
.container {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: 40px;
}

/* Full-width surface band (hero / page head); pages put a .container inside. */
.band {
  background: var(--surface);
  border-block-end: 1px solid var(--line);
}

main { flex: 1; width: 100%; }
main > .container { padding-block: 24px 8px; }

/* Public glyph sizing default. */
.crumbs svg { width: 10px; height: 10px; }

/* --- Brand bar ----------------------------------------------------------
   One quiet brand-blue line (v3): the old per-category strip repeated the
   palette before any content gave it meaning. */

.brandbar { height: 3px; background: var(--brand); }

/* --- Reading progress (F113, injected by site.js) ------------------------
   A fixed hairline over the brandbar line; fills inline-start → inline-end
   (physical right → left on this RTL site). Inside a .cat-scope it inherits
   the post type's accent; elsewhere the brand blue. Sits BELOW the sticky
   admin bar when one is mounted (--admin-bar-h, 0 for visitors) — the admin
   bar must never cover any piece of the site design. */
.read-progress {
  position: fixed;
  inset-block-start: var(--admin-bar-h);
  inset-inline: 0;
  height: 3px;
  z-index: 60;
  background: var(--brand);
  transform: scaleX(0);
  transform-origin: right;
  pointer-events: none;
}
.cat-scope .read-progress { background: var(--type-color); }

/* --- Header ------------------------------------------------------------ */

.site-header { background: var(--surface); border-block-end: 1px solid var(--line); }
.site-header .container {
  max-width: 1200px;
  padding-inline: 40px;
  padding-block: 16px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 20px;
}

.site-name { flex: none; font-weight: 800; font-size: 21px; color: var(--ink); }
.site-name:hover { color: var(--ink); }
.site-logo { display: block; max-height: 2.4rem; width: auto; }

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 3px;
  margin-inline-start: 6px;
}
.site-nav a {
  color: var(--ink-3);
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 15px;
  transition: color 0.18s ease, background-color 0.18s ease;
}
.site-nav a:hover { color: var(--type-color); background: var(--c-panel); }
.site-nav a[aria-current] { color: var(--type-color); background: var(--c-panel); font-weight: 700; }

/* Hamburger toggle (F103) — phone-only; desktop keeps the inline menu. The
   chevron follows the repo disclosure contract (down when closed). Collapse
   only engages under .nav-collapsible (set by site.js), so a no-JS phone
   still sees the full menu. */
.nav-toggle {
  display: none;
  align-items: center;
  gap: 5px;
  padding: 8px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink-3);
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease;
}
.nav-toggle:hover { color: var(--brand); border-color: var(--brand); }
.nav-toggle-icon { width: 18px; height: 18px; }
.nav-toggle-chevron { width: 12px; height: 12px; transition: transform 0.18s ease; }
.site-header.nav-open .nav-toggle-chevron { transform: rotate(180deg); }
@media (max-width: 48rem) {
  .nav-toggle { display: inline-flex; }
  .nav-collapsible .site-nav { display: none; }
  .site-header.nav-open .site-nav {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding-block: 6px 2px;
  }
  .site-header.nav-open .site-nav a { border-radius: 12px; }
}

/* Round search icon-button at the far inline-end (design §10 header). */
.nav-search-btn {
  margin-inline-start: auto;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--paper);
  color: var(--ink-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.18s ease, border-color 0.18s ease;
}
.nav-search-btn:hover { color: var(--brand); border-color: var(--brand); }
.nav-search-btn svg { width: 17px; height: 17px; }

/* 769px–960px (between the hamburger and the guaranteed one-row desktop
   header): logo + full nav + search cannot share a row, and flex-wrap used
   to stack them into THREE rows (~345px of header on a landscape phone —
   the search circle wrapped onto a row of its own). Pin the search button
   onto the logo row instead; the nav wraps to row two and the header stays
   two rows. The reserved padding keeps row content from sliding under the
   pinned button. */
@media (min-width: 48.0625rem) and (max-width: 60rem) {
  .site-header .container { position: relative; padding-inline-end: 96px; }
  .nav-search-btn {
    position: absolute;
    inset-inline-end: 40px;
    inset-block-start: 16px;
    margin-inline-start: 0;
  }
}

/* --- Footer ------------------------------------------------------------ */

.site-footer {
  margin-block-start: 20px;
  border-block-start: 1px solid var(--line-strong);
  background: var(--sand);
  color: var(--ink-3);
  padding-block: 24px;
}
.footer-top { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.footer-brand { font-weight: 800; font-size: 17px; color: var(--ink); }
.footer-tagline { color: var(--ink-3); font-size: 14px; }
.footer-nav { margin-inline-start: auto; display: flex; flex-wrap: wrap; gap: 4px; }
.footer-nav a {
  color: var(--ink-3);
  font-size: 14px;
  padding: 6px 10px;
  border-radius: 8px;
  transition: color 0.18s ease;
}
.footer-nav a:hover { color: var(--type-color); }
/* F165: admin-configured link columns (settings → پابرگ → ستون‌های پیوند). */
.footer-columns {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 18px 24px;
  margin-block-start: 18px;
  padding-block-start: 16px;
  border-block-start: 1px solid var(--line);
}
.footer-column-title { margin: 0 0 6px; font-size: 13.5px; font-weight: 800; color: var(--ink-2); }
.footer-column ul { list-style: none; margin: 0; padding-inline-start: 0; display: flex; flex-direction: column; gap: 2px; }
.footer-column a { display: inline-block; color: var(--ink-3); font-size: 14px; padding-block: 3px; transition: color 0.18s ease; }
.footer-column a:hover { color: var(--type-color); }
.footer-about { color: var(--ink-3); font-size: 14px; margin-block: 12px 0; max-width: 620px; }
.footer-social { display: flex; flex-wrap: wrap; gap: 4px 16px; list-style: none; padding-inline-start: 0; margin-block: 10px 0; font-size: 14px; }
.footer-copy { color: var(--ink-3); font-size: 13.5px; margin-block: 12px 0 0; }
.footer-enamad { margin-block-start: 12px; }

/* --- Buttons & chips ---------------------------------------------------- */

/* Primary button — ALWAYS the brand blue (v3): actions never wear category
   color, so "blue = something you can do" stays learnable. */
.search-btn {
  font: inherit;
  font-size: 15.5px;
  font-weight: 700;
  background: var(--brand);
  color: #ffffff;
  border: none;
  border-radius: 14px;
  padding: 12px 28px;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(25, 87, 127, 0.2);
  transition: background-color 0.18s ease;
}
.search-btn:hover { background: var(--brand-dark); }
.search-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* F107/F146: icon-only variant — «جست‌وجو» was too long for a button; the
   name rides on aria-label instead. SQUARE: the flex row stretches the
   height to the input; the width is pinned to match (aspect-ratio does not
   transfer through stretched flex heights in Blink). */
.search-btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  width: 50px;
  flex: none;
}
.search-btn-icon svg { display: block; width: 19px; height: 19px; }

/* Quiet chip — «همه», copy-link, secondary actions. */
.quiet-chip,
.see-all {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface);
  border: 1px solid var(--c-chip);
  padding: 9px 16px;
  border-radius: 999px;
  color: var(--type-color);
  font-weight: 700;
  font-size: 14px;
  white-space: nowrap;
  transition: border-color 0.18s ease;
}
.quiet-chip:hover,
.see-all:hover { border-color: var(--type-color); color: var(--type-color); }
.quiet-chip svg,
.see-all svg { width: 14px; height: 14px; }

/* --- Search field ------------------------------------------------------- */

.search-form {
  display: flex;
  gap: 10px;
  max-width: 620px;
  position: relative; /* anchors the suggest dropdown */
}
.search-form input[type='search'] {
  flex: 1;
  min-width: 0;
  font: inherit;
  font-size: 16px;
  color: var(--ink);
  background: var(--surface);
  border: 1.5px solid var(--line-input);
  border-radius: 14px;
  /* Fixed height (F146): the icon submit button stretches to the row, so a
     known height is what makes its pinned width a true square. */
  height: 50px;
  padding: 0 18px;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
/* Focus is immediate and unmistakable: brand border + soft brand halo.
   (In-category search stays brand too — search is an action, v3.) */
.search-form input[type='search']:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-ring);
}

/* --- Breadcrumb ---------------------------------------------------------- */

/* A flex row (not just the inner <ol>) so the copy-link pill toc.js appends
   after the list lands on the SAME row, pushed to the far inline-end by its
   own margin-inline-start:auto, instead of wrapping onto its own line. */
.crumbs { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 14px; font-size: 13.5px; margin: 0; }
.crumbs-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  list-style: none;
  padding-inline-start: 0;
  margin: 0;
}
.crumbs-list li { display: flex; align-items: center; gap: 8px; margin: 0; }
.crumbs a { color: var(--ink-3); transition: color 0.18s ease; }
.crumbs a:hover { color: var(--type-color); }
.crumbs svg { color: var(--chev); flex: none; }
.crumbs .crumbs-current { color: var(--ink); font-weight: 700; }

/* --- Hero (home) --------------------------------------------------------- */

.hero .container { padding-block: 46px 40px; }
.hero-eyebrow { font-size: 13px; font-weight: 800; letter-spacing: 0.12em; color: var(--brand); }
.hero h1 { font-size: 2.25rem; line-height: 1.4; margin: 12px 0; }
.hero-sub { font-size: 18px; color: var(--ink-3); max-width: 620px; margin: 0 0 26px; }
/* Richtext hero subtitle (F70): inner paragraphs must not double the block gap. */
.hero-sub p { margin: 0 0 0.5em; }
.hero-sub p:last-child { margin-block-end: 0; }

/* Category entry tiles under the hero search — F126: ONE shared responsive
   grid for the homepage groups (hero entry tiles AND the explorer's preview
   card grid): 3 columns at desktop, 2 on tablets, 1 on phones. The preview
   grid is written as the compound .card-grid.cat-exp-grid so these fixed
   column counts outrank the generic .card-grid auto-fill columns (defined
   further down) regardless of source order — a bare single-class selector
   ties with .card-grid and silently loses to it (that bug shipped 4 desktop
   columns once, on the retired spotlight grid). */
.cat-tiles,
.card-grid.cat-exp-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.cat-tiles { margin-block-start: 24px; }
@media (max-width: 860px) { .cat-tiles, .card-grid.cat-exp-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px) { .cat-tiles, .card-grid.cat-exp-grid { grid-template-columns: 1fr; } }
.cat-tile {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 11px 16px;
  color: var(--ink);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.cat-tile:hover {
  color: var(--ink);
  transform: translateY(-2px);
  border-color: var(--c-chip);
  box-shadow: 0 8px 20px var(--c-shadow);
}
/* Icon containers are one system: 44px, 12px radius, accent fill, near-white
   glyph (24px) — identical in the hero tiles and the section heads. */
.cat-tile-icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  /* F74: tinted tile + accent glyph (the dashboard type-card treatment) —
     the solid accent fill put a white stroke icon on dark hues that don't
     all carry it well. Same swap on every icon tile below. */
  background: var(--c-tile);
  color: var(--type-color);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.cat-tile-icon svg { width: 24px; height: 24px; }
.cat-tile-text { flex: 1; min-width: 0; }
/* F126: medium weight, ONE line — overflow ellipsizes (site.js surfaces the
   full text via tooltip only when truncation really happens). */
.cat-tile-name {
  display: block;
  font-size: 15.5px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.7;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* (.cat-tile-count retired with F110 — homepage tiles carry no item counts.) */
.cat-tile-chevron { width: 16px; height: 16px; flex: none; color: var(--type-color); }

/* --- Category explorer (partials/category-explorer.njk) ------------------ */
/* Inline category exploration inside a section panel: count-ordered selector
   BUTTONS (a TAB strip on desktop — no chevron; the CLAUDE.md chevron rule
   excepts tab-style selectors) + preview PANELS of shared item cards. The
   DOM is button,panel,button,panel… (right for AT, no-JS and phones); on
   wider screens CSS `order` floats every panel below the button grid, so the
   one open panel reads as a single shared full-width preview area — buttons
   keep their rows, nothing shifts inside the grid. The panel's own TITLE
   (category name + count) provides the context and the separation from the
   selector grid. The server ships the first category active, the rest
   hidden; site.js only wires the one-open switching. */
.cat-explorer { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.cat-exp-btn {
  order: 0;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 11px 16px;
  font: inherit;
  text-align: start;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.18s ease, background-color 0.18s ease, box-shadow 0.18s ease;
}
.cat-exp-btn:hover { border-color: var(--c-chip); box-shadow: 0 8px 20px var(--c-shadow); }
/* Selected (active-tab) state never rides on color alone: accent border +
   tinted fill + the BOLD name all mark it. */
.cat-exp-btn[aria-expanded="true"] {
  background: var(--c-wash);
  border-color: var(--type-color);
  box-shadow: none;
}
.cat-exp-btn[aria-expanded="true"] .cat-exp-name { font-weight: 700; }
.cat-exp-name {
  flex: 1;
  min-width: 0;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.7;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* (Counts live ONLY in the view-all tile's label — tabs and the panel title
   carry the bare category name.) */
.cat-exp-panel { order: 1; grid-column: 1 / -1; margin-block-start: 18px; }
.cat-exp-panel[hidden] { display: none; }
/* Panel title: the selected category's name right above its items — the
   context AND the visual separation from the selector grid. */
.cat-exp-title {
  margin: 0 0 12px;
  font-size: 16px;
  font-weight: 800;
  color: var(--ink);
  line-height: 1.6;
}
@media (max-width: 860px) { .cat-explorer { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px) {
  .cat-explorer { grid-template-columns: 1fr; }
  /* True accordion on phones: source order puts each panel under its button —
     the button directly above already names the category, so no panel title. */
  .cat-exp-btn, .cat-exp-panel { order: initial; }
  .cat-exp-panel { margin-block-start: 0; }
  .cat-exp-title { display: none; }
}

/* --- Category panel + content cards (home & listings) -------------------- */

.home-section { margin-block-end: 20px; }
.home-section:target { scroll-margin-block-start: calc(16px + var(--sticky-bars)); }

/* White card everywhere (home sections and listing pages alike) — a tinted
   panel on just one section/page read as a different, heavier design than
   the rest of the system, so every category panel now shares one flat,
   white, bordered surface. */
.category-panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: 26px;
}

.panel-head { display: flex; align-items: center; gap: 14px; margin-block-end: 18px; }
.panel-head-icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--c-tile);
  color: var(--type-color);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.panel-head-icon svg { width: 24px; height: 24px; }
.panel-head-text { flex: 1; min-width: 0; }
.panel-head h2 { margin: 0; line-height: 1.45; }
.panel-sub { display: block; font-size: 14px; color: var(--ink-2); line-height: 1.7; }

/* Taxonomy term descriptions (F68): under the section heading on grouped
   overviews, and under the title block on a term's own filter page. */
.panel-desc { margin: -8px 0 16px; max-width: 70ch; font-size: 14.5px; color: var(--ink-2); }
.panel-desc p, .listing-desc p { margin: 0 0 0.5em; }
.panel-desc p:last-child, .listing-desc p:last-child { margin-block-end: 0; }
.listing-desc { margin-block-start: 10px; max-width: 70ch; font-size: 15px; color: var(--ink-2); line-height: 1.9; }

/* The trailing "uncategorized" bucket is a content gap (a doc missing its
   grouping field), not a real category — dashed border + neutral ink icon
   (never the type's own accent color) so it reads as "needs attention"
   rather than sitting as an equally legitimate section next to real ones. */
.category-panel--uncategorized { border: 1px dashed var(--line-strong); }
.panel-head-icon--muted { background: var(--sand); color: var(--ink-3); }

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
  gap: 12px;
}
/* (The homepage explorer grid's column counts live beside .cat-tiles above,
   as .card-grid.cat-exp-grid — the compound outranks this auto-fill rule so
   the homepage keeps its fixed 3/2/1 columns. A duplicate rule HERE once
   overrode the 860/540px overrides and forced three squeezed columns on
   phones, F141. Never restate them below the queries.) */

/* Grouped listing overviews (the /skills/-style top-level pages): fixed TWO
   columns on desktop, one on phones (owner decision 2026-08-04 — was the
   auto-fill ≈3 beside the filter sidebar). Pairs with sectionPreview's 7/10
   listing numbers (listing.ts): a full 7-item preview + the view-all tile
   close the grid as a clean 2×4. Descendant selector so it outranks the
   auto-fill base above regardless of source order (same specificity lesson
   as .card-grid.cat-exp-grid); breakpoint matches the explorer's 2→1. */
.listing-main .card-grid { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 540px) { .listing-main .card-grid { grid-template-columns: 1fr; } }
/* F141: one-line (nowrap) card titles must never dictate the column width —
   grid items default to min-width:auto, which let a long title push the
   whole grid past the viewport on phones. */
.card-grid > *, .cat-tiles > * { min-width: 0; }

/* Trailing view-all TILE — shared by every grouped listing overview section
   AND the homepage explorer panels: the card grid's LAST cell, so a full
   preview closes the desktop grid without an empty slot (explorer: 8 + tile
   = 3×3; listing overview: 7 + tile = 2×4); on narrower column counts it
   simply ends the list. Dashed border + accent text keep it "meta" next to
   the solid content cards. */
.card-grid .see-all-card {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px dashed var(--c-chip);
  border-radius: 14px;
  padding: 12px 16px;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--type-color);
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.card-grid .see-all-card:hover { background: var(--c-wash); border-color: var(--type-color); color: var(--type-color); }
.card-grid .see-all-card svg { width: 15px; height: 15px; flex: none; }

/* Content card — the workhorse doorway card. */
.card-grid .relation-card,
.listing .relation-card {
  display: flex;
  flex-direction: column;
  gap: 7px;
  background: var(--surface);
  border: 1px solid var(--c-border);
  border-radius: 14px;
  padding: 17px 18px 13px;
  color: var(--ink);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease,
    color 0.18s ease, background-color 0.18s ease;
}
/* F126: the slim doorway card is ONE horizontal row — title and chevron on
   the same line, vertically centered; no bottom-corner chevron, no second
   line. Shared by the homepage explorer previews and every listing grid.
   (Doubled class keeps it above the `.card-grid .relation-card` column
   rule.) */
.relation-card.relation-card-slim { flex-direction: row; align-items: center; gap: 10px; padding: 12px 16px; }
.relation-card-slim .relation-card-title {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: 15.5px;
  font-weight: 500;
  line-height: 1.7;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.relation-card-slim .relation-card-chevron { flex: none; }
/* Hover = clearer tinted border + gentle lift; the text stays ink (v3: no
   dramatic color flips) and only the chevron carries the accent. */
.relation-card:hover {
  border-color: var(--c-chip);
  box-shadow: 0 8px 20px var(--c-shadow);
  transform: translateY(-2px);
  color: var(--ink);
}
.relation-card-head { min-width: 0; }
.relation-card-title { display: block; font-weight: 800; font-size: 16.5px; line-height: 1.5; margin: 0; color: inherit; }
.relation-card-summary {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* F78: quieter than before (was 14px/--ink-3, 3 lines) — the summary is a
     scent, not the content; it must not compete with the card title. */
  color: var(--ink-4);
  font-size: 13px;
  line-height: 1.7;
}
.relation-card-foot { display: flex; justify-content: flex-end; margin-block-start: auto; padding-block-start: 4px; }
.relation-card-chevron { width: 14px; height: 14px; color: var(--type-color); }

/* Screen-reader-only text (the tooltip summary's accessible copy). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* (The custom black data-tip bubble on cards was retired 2026-08-03 — cards
   are title-only; the summary stays as sr-only text for screen readers, and
   a truncated title falls back to the native title tooltip via site.js.) */

/* --- Listing page --------------------------------------------------------- */

.listing-head .container { padding-block: 24px 30px; }
.listing-title-row { display: flex; align-items: center; gap: 16px; margin-block-start: 20px; }
.listing-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  background: var(--c-tile);
  color: var(--type-color);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.listing-icon svg { width: 25px; height: 25px; }
.listing-title-text { flex: 1; min-width: 0; }
.listing-title-line { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.listing-head h1 { font-size: 30px; margin: 0; }
.count-chip {
  background: var(--c-tile);
  color: var(--type-color);
  border-radius: 999px;
  padding: 3px 13px;
  font-size: 13px;
  font-weight: 800;
  white-space: nowrap;
}
.listing-section { margin-block-end: 20px; }
.listing-section:last-child { margin-block-end: 0; }
.listing-main { min-width: 0; }
.listing-section .panel-head h2 { font-size: 20px; }

/* F108: search + filters live in the listing sidebar now — one quiet card
   sharing the doc-sidebar chrome (sticky on desktop, drawer on phones). */
/* Sidebar head (explore): overline + ONE quiet reset action on a single row
   — replaces the stacked clear links that used to sit between the search box
   and the filter accordions. */
.listing-tools-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.filters-reset { flex: none; font-size: 12px; font-weight: 700; color: var(--ink-3); padding-block-end: 8px; }
.filters-reset:hover { color: var(--type-color); }

.listing-tools .search-form { margin-block-start: 2px; }
/* Inline padding stays with the .search-box rules (room for the prepended
   magnifier / appended ✕) — this higher-specificity rule once reset it to
   14px and ran the text under the icon. */
.listing-tools .search-form input[type='search'] { height: 44px; padding-block: 0; font-size: 14.5px; }
.listing-tools .search-btn-icon { width: 44px; border-radius: 12px; }
.listing-tools .search-btn-icon svg { width: 16px; height: 16px; }

/* Filter bar (per-field value listings). */
.filter-groups { display: flex; flex-direction: column; gap: 8px; margin-block-start: 18px; }
.filter-group { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* Sidebar variant (F130): accordion groups separated by hairlines. */
.filter-groups-sidebar { margin-block-start: 10px; gap: 0; }
.filter-groups-sidebar .filter-group {
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  border-block-start: 1px solid var(--line-soft);
}
.filter-groups-sidebar .filter-options {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  padding-block-end: 12px;
}
.filter-options[hidden] { display: none; }
/* Accordion header: a real button — label, active count, closed-state-down
   chevron; whole row is the hit target. */
.filter-acc-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 11px 2px;
  background: none;
  border: none;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-2);
  cursor: pointer;
  text-align: start;
}
.filter-acc-btn:hover { color: var(--ink); }
.filter-acc-label { flex: 1; min-width: 0; }
.filter-acc-count {
  flex: none;
  min-width: 19px;
  height: 19px;
  padding-inline: 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--c-tile);
  color: var(--type-color);
  font-size: 11.5px;
  font-weight: 800;
  line-height: 1;
}
.filter-acc-chevron { width: 13px; height: 13px; flex: none; color: var(--chev); transition: transform 0.18s ease; }
.filter-acc.open .filter-acc-chevron { transform: rotate(180deg); }
/* F129: the primary clear-everything action — a real labeled control, shown
   only while something is filtered. */
.filter-clear-all {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-block-start: 12px;
  padding: 7px 14px;
  border: 1px dashed var(--line-strong);
  border-radius: 999px;
  align-self: flex-start;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 700;
  transition: color 0.18s ease, border-color 0.18s ease;
}
.filter-clear-all:hover { color: var(--type-color); border-color: var(--type-color); }
/* Compact «نمایش بیشتر» inside a filter group (shares .list-more-btn). */
.list-more-btn-sm { margin-block-start: 2px; padding: 4px 12px; font-size: 12.5px; }
.filter-pill[hidden] { display: none; }
.filter-label { font-size: 13.5px; font-weight: 700; color: var(--ink-3); margin-inline-end: 2px; }
.filter-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-3);
  font-size: 13.5px;
  font-weight: 700;
  transition: color 0.18s ease, border-color 0.18s ease;
}
.filter-pill:hover { color: var(--type-color); border-color: var(--type-color); }
.filter-pill.active { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.filter-pill.active:hover { color: var(--paper); }
/* No opacity and ≥11.5px: counts inherit the pill's ink-3, which is the
   lightest ink that still clears WCAG AA on surface. */
/* (.filter-count retired 2026-08-03 — filter pills carry no result counts.) */
.filter-clear { border-style: dashed; }

/* --- Pagination ----------------------------------------------------------- */

.pager, .search-pagination {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-block-start: 24px;
}
.pager a, .pager span, .search-pagination a, .search-pagination span {
  min-width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding-inline: 8px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 700;
}
.pager a, .search-pagination a {
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink-3);
  transition: color 0.18s ease, border-color 0.18s ease;
}
.pager a:hover, .search-pagination a:hover { color: var(--type-color); border-color: var(--type-color); }
.pager .pager-cur { background: var(--ink); border: 1px solid var(--ink); color: var(--paper); }
.pager .pager-gap { color: var(--ink-4); min-width: auto; padding-inline: 4px; }
.pager svg, .search-pagination svg { width: 13px; height: 13px; }

/* --- Document (detail) pages ---------------------------------------------- */

.doc-head .container { padding-block: 24px 30px; }

.doc-title-row { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-block-start: 14px; }
.doc-title-text { flex: 1; min-width: 0; }
/* Slightly under the global 2rem h1 — the content H1 shares the band with
   breadcrumbs and the logo, so it reads calmer a notch smaller. */
.doc-head h1.doc-title { margin: 0; font-size: 1.8rem; }
/* Full container width — the sidebar column only exists below, in the grid. */

/* Share button (F102, injected by site.js on the breadcrumb row, pushed to
   the far inline-end — the physical LEFT on this RTL site — on every page
   template that shares crumbs.njk: content pages and listing pages alike).
   Icon-only; the success feedback is the ::after bubble below. */
.doc-share-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--c-chip);
  border-radius: 999px;
  color: var(--type-color);
  cursor: pointer;
  transition: border-color 0.18s ease;
}
.doc-share-btn:hover { border-color: var(--type-color); }
/* display:block kills the inline-svg baseline slack that nudged the glyph
   off-center inside the circle (F143). */
.doc-share-btn svg { display: block; width: 15px; height: 15px; }
/* F157: share + copy travel as ONE group at the far inline-end — their own
   6px gap, immune to the crumbs row's gap and wrapping. */
.doc-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-inline-start: auto;
}
/* Hover hint + copy feedback share one bubble (same pattern as the heading
   anchors); .copied swaps the text and pins it visible. */
.doc-share-btn::after {
  content: attr(data-tipword);
  position: absolute;
  top: calc(100% + 7px);
  inset-inline-start: 50%;
  translate: 50% 0; /* RTL page: physical +x shift centers the bubble */
  background: var(--ink);
  color: var(--paper);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  padding: 6px 10px;
  border-radius: 7px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease 0.15s;
  z-index: 5;
}
.doc-share-btn.copied::after { content: 'لینک صفحه کپی شد'; }
@media (hover: hover) {
  .doc-share-btn:hover::after,
  .doc-share-btn:focus-visible::after { opacity: 1; visibility: visible; }
}
.doc-share-btn.copied::after { opacity: 1; visibility: visible; }

/* Grid: 280px sticky sidebar (right, in RTL) + article. */
.doc-layout {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  gap: 26px;
  align-items: start;
  padding-block: 26px 8px;
}
.doc-layout.no-sidebar { grid-template-columns: minmax(0, 1fr); }

/* Tool logo beside the title. */
.doc-logo { margin: 6px 0 0; flex: none; }
.doc-logo img { max-height: 72px; width: auto; border-radius: 13px; display: block; background: var(--surface); }

/* Sidebar type scale (T2): one tier set for every sidebar component —
   values/TOC links 14 · labels/badges/EN title 12.5 · notes/overline 12;
   the card title (15) is the single deliberate step up. New sidebar
   components take a variable instead of hand-picking a size. */
.doc-sidebar {
  --sb-value: 14px;
  --sb-label: 12.5px;
  --sb-note: 12px;
  --sb-title: 15px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}
@media (min-width: 64rem) {
  .doc-sidebar {
    position: sticky;
    /* Stick BELOW the logged-in admin bar (F52): without the offset the
       sidebar's top slid underneath the sticky bar while scrolling. The
       height cap shrinks by the same amount so the bottom stays on-screen. */
    top: calc(24px + var(--sticky-bars));
    max-height: calc(100dvh - 48px - var(--sticky-bars));
    overflow-y: auto;
    /* F148: sticky forms a stacking context in Blink — without an explicit
       level, the results column painted OVER the suggestion panel. */
    z-index: 10;
  }
  /* F79: scrolling the WHOLE column cut the TOC card (and its bottom border)
     at the viewport cap. Instead the cards keep their natural height and the
     TOC's LIST scrolls inside its own bordered card: min-height:0 lets the
     card compress within the flex column, the ul takes the scrollbar. The
     container's overflow-y:auto stays only as a fallback for the extreme
     case of a glance card alone exceeding the viewport. */
  .doc-sidebar > * { flex: none; }
  .doc-sidebar > .doc-toc { flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; }
  .doc-sidebar > .doc-toc > * { flex: none; }
  .doc-sidebar > .doc-toc > ul { flex: 0 1 auto; min-height: 0; overflow-y: auto; }
  /* LISTING/SEARCH sidebars are never an inner scroll container (F130: the
     page scrolls, accordions keep the column short) — a capped overflow here
     also CLIPPED the suggestion panel at the card edge (F128) and grew a
     stray horizontal scrollbar under the sidebar. */
  .doc-sidebar.listing-sidebar { max-height: none; overflow: visible; }
}

/* Sidebar fact card (alternative names, learning time, tool facts). */
.glance {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 16px 19px;
}
.glance-rows { margin-block-start: 0; }
/* F163: label and value(s) share one wrapping line — the label leads, badges
   flow after it and wrap to full-width lines when a row carries many. Gap
   replaces the old per-value margins. */
.glance-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 10px;
  row-gap: 4px;
  border-block-start: 1px solid var(--line-soft);
  padding-block: 10px;
}
.glance-row:first-child { border-block-start: 0; padding-block-start: 2px; }
.glance-row:last-child { padding-block-end: 2px; }
/* F164: the outward-links block (official site …) sits apart from the fact
   rows above it. Only the first links row gets the extra lead-in. */
.glance-row:not(.glance-row-links) + .glance-row-links { padding-block-start: 18px; }
.glance-label { flex: none; font-size: var(--sb-label); font-weight: 700; color: var(--ink-3); }
.glance-value { font-size: var(--sb-value); font-weight: 700; color: var(--ink); }
.glance-value.glance-latin { text-align: left; letter-spacing: 0.01em; }
/* An emphasized numeric value (learning hours, …) is a STAT, not a link, so
   it takes the category accent inside a tinted pill rather than plain
   colored text — plain accent text next to real `<a>` pills in this same
   sidebar reads as another link. Linked values are actions → brand blue (v3). */
.glance-value-pill {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  padding: 3px 12px;
  border-radius: 999px;
  background: var(--c-tile);
  color: var(--type-color);
  font-size: var(--sb-value);
  font-weight: 800;
}
.glance-value a { color: var(--brand); }
/* GlanceTag: plain inline text, one value per line — the sidebar's own
   role for a multi-value fact (alternative names, platform list), distinct
   from the filled pill `.badge` wears in the article body, so one class
   name doesn't carry two unrelated looks depending on where it lands. */
.glance-tag { display: inline; }
a.glance-tag { color: var(--brand); }
a.glance-tag:hover { color: var(--brand-dark); }

/* PageToc — «در این صفحه» (scroll-spy adds .active) */
.doc-toc {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 14px 12px;
}
.doc-toc-overline {
  font-size: var(--sb-note);
  font-weight: 800;
  letter-spacing: 0.12em;
  color: var(--ink-3);
  padding: 0 7px 8px;
  margin: 0;
}
.doc-toc ul { list-style: none; padding-inline-start: 0; margin: 0; display: flex; flex-direction: column; gap: 2px; }
.doc-toc li { margin: 0; }
.doc-toc a {
  display: block;
  padding: 8px 13px;
  border-radius: 9px;
  font-size: var(--sb-value);
  line-height: 1.6;
  color: var(--ink-3);
  transition: color 0.18s ease, background-color 0.18s ease;
  /* F134: one line per entry, always — short labels come from the framing
     engine; anything still longer ellipsizes instead of wrapping. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.doc-toc a:hover { color: var(--type-color); }
.doc-toc a.active { background: var(--c-panel); color: var(--type-color); font-weight: 700; }
.doc-toc .toc-sub a { padding-inline-start: 26px; font-size: 13px; }

/* Entity identity at the top of the FIRST sidebar card: the type pill as an
   eyebrow, the short content title under it at full card width, the English
   name last — always visible (the H1 carries the descriptive SEO title
   instead). column-reverse: the pill is LAST in the shared markup but reads
   first; a side-by-side layout crushed long guide titles against the pill. */
.sidebar-id {
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-start;
  gap: 7px;
  border-block-end: 1px solid var(--line-soft);
  padding-block-end: 10px;
  margin-block-end: 8px;
}
.sidebar-id:last-child { border-block-end: 0; padding-block-end: 2px; margin-block-end: 0; }
.doc-toc .sidebar-id { padding-inline: 7px; }
.sidebar-id-text { min-width: 0; align-self: stretch; }
.sidebar-title { font-size: var(--sb-title); font-weight: 800; color: var(--ink); line-height: 1.6; margin: 0; }
/* Right-aligned: in the identity block there are only the two titles (fa + en),
   so the English one hugs the same edge as the Persian title. (The career
   page's multi-name English list uses .glance-latin and stays left-aligned.) */
.sidebar-title-en {
  font-size: var(--sb-label);
  font-weight: 400;
  color: var(--ink-3);
  letter-spacing: 0.02em;
  text-align: right;
  line-height: 1.6;
  margin: 2px 0 0;
}
/* Content-type pill: the eyebrow above the title (see .sidebar-id). */
.sidebar-type {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--c-tile);
  color: var(--type-color);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 11.5px;
  font-weight: 800;
  line-height: 1.8;
  white-space: nowrap;
}
.sidebar-type-icon { width: 1.05em; height: 1.05em; flex: none; }
/* F162: the chip links to its type's listing; hover follows a.badge (tile
   pill deepens its text, no underline). */
a.sidebar-type { transition: color 0.18s ease; }
a.sidebar-type:hover { color: var(--c-dark); }

/* Article column */
.doc { display: flex; flex-direction: column; gap: 18px; min-width: 0; }

.doc-section {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: 26px 30px 28px;
  scroll-margin-block-start: calc(16px + var(--sticky-bars));
}

/* SectionTitle: 5×26 accent bar + h2. */
.doc-section > h2 {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 14px;
}
.doc-section > h2::before {
  content: '';
  width: 5px;
  height: 26px;
  border-radius: 3px;
  background: var(--type-color);
  flex: none;
}
.doc-section > h2, .doc-section > h3 { scroll-margin-block-start: calc(16px + var(--sticky-bars)); }

.doc-section > h3 { font-size: 16.5px; margin: 0 0 10px; }
.doc-section > * + h3 { margin-block-start: 20px; }

.doc-section p { font-size: 15.5px; color: var(--ink-body); line-height: 1.95; }

.richtext { font-size: 15.5px; color: var(--ink-body); line-height: 1.95; }
.richtext :first-child { margin-block-start: 0; }
.richtext :last-child { margin-block-end: 0; }
/* Authored-prose subsections (owner 2026-08-04): a heading opens a new
   subsection, so it carries extra space ABOVE the 16px paragraph rhythm and
   stays tight to its own content below. All levels — the outline normalizer
   (shiftHeadings, F99) renders authored h2–h4 anywhere from h3 to h6
   depending on render depth. The :first-child rule above already zeroes the
   space at the top of a fragment. */
.richtext h2, .richtext h3, .richtext h4, .richtext h5, .richtext h6 { margin-block-start: 1.7em; }
/* Inline prose links are ACTIONS → brand blue (v3), never category-colored. */
.richtext a { color: var(--brand); font-weight: 700; }
.richtext a:hover { color: var(--brand-dark); }

.doc-cover { margin: 14px 0 0; }
.doc-cover img { border-radius: 16px; display: block; }

/* --- Item lists ------------------------------------------------------------
   The general titled-point component (duties, highlights, applications, key
   features, use cases, …): a 7px accent dot, a bold title, a quiet body.
   Column layout comes from a modifier: .cols-2 / .cols-3 (default: one
   column); all collapse to one column on narrow viewports. */
.item-list {
  list-style: none;
  padding-inline-start: 0;
  margin: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px 26px;
}
.item-list.cols-2 { grid-template-columns: 1fr 1fr; }
.item-list.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 48rem) {
  .item-list.cols-2, .item-list.cols-3 { grid-template-columns: 1fr; }
}
.doc-section > * + .item-list { margin-block-start: 16px; }
.item-list .item {
  position: relative;
  min-width: 0;
  padding-inline-start: 17px;
  margin: 0;
  font-size: 14.5px;
  color: var(--ink-body);
  line-height: 1.85;
}
.item-list .item::before {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 10px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--type-color);
}
.item-title { font-size: 15.5px; font-weight: 800; margin: 0; line-height: 1.6; }
.item-body { font-size: 14px; color: var(--ink-3); margin: 2px 0 0; line-height: 1.85; }

/* Generic field-renderer content inside an .item (field.njk's object_list
   dispatch emits a plain p.item-title/p/.richtext, not real headings — a
   repeated bullet title is a list-item label, not a document subsection, so
   it stays out of the heading outline. Same visual weight as the
   hand-authored item-title/item-body classes, so a generic and a bespoke
   dot-list are indistinguishable. Scoped to the item-list-generic marker
   (not bare .item-list) so it can never out-specificity .item-title/
   .item-body on the hand-authored dot-lists. */
.item-list-generic .item .item-title { margin: 0 0 4px; }
.item-list-generic .item p, .item-list-generic .item .richtext { font-size: 14px; color: var(--ink-3); line-height: 1.85; }
.item-list-generic .item > :last-child { margin-block-end: 0; }
/* Real sub-heading item labels (h3/h4 with .item-heading — the ordered rail
   and the 'titled' presentation, F99/F120). */
.item-list .item .item-heading { font-size: 15.5px; font-weight: 800; margin: 0 0 4px; line-height: 1.6; }
/* 'titled' lists (گرایش‌ها …): the title IS the point — one notch larger,
   with the body kept quiet under it. */
.item-list-titled { gap: 16px 26px; }
.item-list-titled .item .item-heading { font-size: 16.5px; }
.item-list-titled .item p { font-size: 14.5px; }

/* Plain string bullets (سایر پیش‌نیازها …) share the dot treatment. */
.prereq-list {
  list-style: none;
  padding-inline-start: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.prereq-list li {
  position: relative;
  padding-inline-start: 17px;
  margin: 0;
  font-size: 14.5px;
  color: var(--ink-body);
  line-height: 1.85;
}
.prereq-list li::before {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 11px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--type-color);
}

/* Checklists (single-text repeaters) — ✓ marks, no ordering implied. */
.checklist {
  list-style: none;
  padding-inline-start: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.checklist li {
  position: relative;
  padding-inline-start: 26px;
  margin: 0;
  font-size: 15px;
  color: var(--ink-body);
  line-height: 1.85;
}
.checklist li::before {
  content: '✓';
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0;
  font-weight: 800;
  color: var(--type-color, var(--brand));
}

/* Small label over a badge/list group inside repeater items (e.g. per-stage
   skills vs tools) — distinguishes adjacent same-shaped groups. */
.field-mini-label {
  margin: 10px 0 4px;
  font-size: 12.5px;
  font-weight: 800;
  color: var(--ink-3);
}
.learning-step .field-mini-label:first-child { margin-block-start: 0; }

/* Muted one-line intro directly under a section heading (learning-hours
   hint, legacy panel-questions intro). */
.section-intro {
  margin: -2px 0 14px;
  font-size: 14px;
  color: var(--ink-3);
  line-height: 1.9;
}
/* F124: section LEAD — the connective sentence between a section heading and
   its structured contents (framing engine + owner-authored intros). Same
   type family as body prose, visually subordinate to the h2, readable
   measure, no cards/icons/decoration. */
.section-lead {
  margin: -4px 0 16px;
  font-size: 14.5px;
  color: var(--ink-2);
  line-height: 1.95;
  max-width: 70ch;
}
/* F81: checklist lead-in sits mid-section, so it drops the pull-up margin. */
.checklist-intro { margin: 0 0 12px; }
/* F87: alternative-names block inside #sec-intro (career pages). */
.alt-names-lead { margin-block-start: 14px; }
.alt-names-list { margin-block-start: 10px; }

/* Fact tiles (generic renderer key data). */
.fact {
  display: inline-flex;
  flex-direction: column;
  vertical-align: top;
  padding: 8px 16px 9px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  margin-inline-end: 10px;
  margin-block-end: 12px;
}
.fact-row { display: flex; flex-wrap: wrap; gap: 10px; margin-block-end: 18px; }
/* Learning-path closing total (glance goal 2026-08-04): the timeline's
   terminal node — same marker/card/header anatomy as the steps above it, a
   clock in the marker instead of a step number, the qualifier sentence as
   the card body at full width. The emphasized time chip marks it as the
   summary of the per-step chips. */
.learning-path-total { position: relative; padding-inline-start: 58px; margin-block-start: 28px; }
.learning-path-total .learning-step-marker { inset-block-start: 12px; }
.learning-total-icon { width: 20px; height: 20px; }
.learning-total-title { margin: 0; color: var(--ink); font-size: 16px; font-weight: 900; line-height: 1.55; }
.learning-path-total .learning-step-time {
  background: transparent;
  border-color: var(--c-chip);
  color: var(--type-color);
  font-size: 13px;
  font-weight: 800;
}
.learning-hours-note { margin: 0; font-size: 13.5px; color: var(--ink-3); line-height: 1.9; }
/* The rail runs on from the last step into the total node (progressive
   enhancement — without :has() the rail simply ends at the last step). */
.doc-section:has(.learning-path-total) .learning-path-unified .learning-step:last-child::after {
  display: block;
  inset-block-end: -40px;
}
.fact-row .fact { margin: 0; }
.fact-label { font-size: 12.5px; line-height: 1.7; color: var(--ink-3); }
.fact-value { font-size: 15.5px; line-height: 1.7; font-weight: 700; color: var(--ink); }
.fact-value a { color: var(--brand); }

/* Steps — accent-filled number discs on a vertical rail. */
.learning-steps {
  list-style: none;
  padding-inline-start: 0;
  margin: 0;
  counter-reset: learning-step;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.learning-step {
  counter-increment: learning-step;
  position: relative;
  padding-inline-start: 46px;
  margin: 0;
}
.learning-step::before {
  content: counter(learning-step, fa-decimal);
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 2px;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--type-color);
  color: var(--c-on);
  font-weight: 800;
  font-size: 14px;
  line-height: 1;
  box-shadow: 0 0 0 3px var(--c-panel);
}
/* The rail connecting each disc to the next (spans the flex gap). */
.learning-step::after {
  content: '';
  position: absolute;
  inset-inline-start: 15px;
  inset-block-start: 40px;
  inset-block-end: -15px;
  width: 2px;
  border-radius: 999px;
  background: var(--c-border);
}
.learning-step:last-child::after { display: none; }
/* h3 OR h4 — the item heading level follows the outline (F99). */
.learning-step h3, .learning-step h4 { font-size: 15.5px; font-weight: 800; margin: 0 0 4px; line-height: 1.6; }
.learning-step p, .learning-step .richtext { font-size: 14px; color: var(--ink-3); line-height: 1.85; }
.learning-step > :last-child { margin-block-end: 0; }

/* Hours chip on the step title row: a quiet outlined pill in the family. */
.step-hours-chip {
  display: inline-block;
  margin-inline-start: 8px;
  padding: 0 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.9;
  background: var(--surface);
  border: 1px solid var(--c-border);
  color: var(--c-dark);
  vertical-align: 0.12em;
  white-space: nowrap;
}
p.step-hours-chip { margin: 0 0 4px; }

.section-meta { color: var(--ink-3); font-size: 14px; margin: -6px 0 16px; }

/* --- Related groups: destination-colored panels of compact cards ---------- */

.relation-group {
  background: var(--c-panel);
  border-radius: 18px;
  padding: 14px;
}
.doc-section .relation-group + .relation-group,
.doc-section * + .relation-group { margin-block-start: 12px; }
.relation-group-head { display: flex; align-items: center; gap: 10px; margin-block-end: 10px; }
.relation-group-icon {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--c-tile);
  color: var(--type-color);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.relation-group-icon svg { width: 18px; height: 18px; }
.relation-group-title { font-size: 16px; font-weight: 800; color: var(--ink); margin: 0; line-height: 1.6; }

.relation-cards {
  list-style: none;
  padding-inline-start: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(13rem, 100%), 1fr));
  gap: 10px;
}
.relation-cards li { margin: 0; }
.relation-cards .relation-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  height: 100%;
  background: var(--surface);
  border: 1px solid var(--c-border);
  border-radius: 12px;
  padding: 12px 14px;
  color: var(--ink);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.relation-cards .relation-card:hover {
  border-color: var(--c-chip);
  box-shadow: 0 8px 18px var(--c-shadow);
  transform: translateY(-2px);
  color: var(--ink);
  background: var(--surface);
}
.relation-cards .relation-card-title { font-size: 15px; font-weight: 800; line-height: 1.5; }
.relation-cards .relation-card-summary { font-size: 12.5px; }
.relation-card-kind {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 800;
  line-height: 1.6;
  color: var(--type-color);
}
.relation-card-kind-icon { width: 14px; height: 14px; flex: none; }

/* Mixed lists (backlinks): each row carries its own category family — a soft
   tile icon (`c-tile` fill + `type-color` glyph, unlike the solid-fill tiles
   above) plus a stacked kind/title/latin text block.
   F135: a responsive GRID (two columns on desktop article widths, one on
   narrow screens) — a single full-width column wasted half the line. */
.relation-rows {
  list-style: none;
  padding-inline-start: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(21rem, 100%), 1fr));
  gap: 12px;
}
.relation-rows li { margin: 0; }
.relation-row {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--surface);
  border: 1px solid var(--c-border);
  border-radius: 16px;
  padding: 14px 20px;
  color: var(--ink);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.relation-row:hover {
  border-color: var(--c-chip);
  box-shadow: 0 8px 18px var(--c-shadow);
  transform: translateY(-2px);
  color: var(--ink);
}
/* F149/F151: the shared TYPE CHIP in the leading slot — one identity
   component for relation rows, related items and explore results. ICON
   only (F151: visible names disrupted rows); the type name rides as sr-only
   text + a native title tooltip. */
.type-chip {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: var(--c-tile);
  color: var(--type-color);
}
.type-chip-icon { display: block; width: 20px; height: 20px; flex: none; }

.relation-row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.relation-row-title { font-size: 15.5px; font-weight: 700; line-height: 1.6; color: var(--ink); }
.relation-row-latin { align-self: stretch; font-size: 13px; font-weight: 400; color: var(--ink-3); letter-spacing: 0.02em; text-align: right; }
/* F100 (2026-08-02): the Latin title stays OFF (the markup still ships it —
   restoring it is deleting this line). The kind label returned inside the
   type chip (F149). */
.relation-row-latin { display: none; }
.relation-row-chevron { width: 17px; height: 17px; flex: none; color: var(--chev); }

/* --- External reference / resource cards ----------------------------------- */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(14.5rem, 100%), 1fr));
  gap: 10px;
}
ul.cards { list-style: none; padding-inline-start: 0; margin: 0; }
.cards > li { margin: 0; }

.card, .ref-card {
  display: block;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px 14px;
  color: var(--ink);
  transition: border-color 0.18s ease, box-shadow 0.18s ease, color 0.18s ease;
}
a.card:hover, a.ref-card:hover {
  border-color: var(--c-chip);
  box-shadow: 0 8px 18px var(--c-shadow);
  color: var(--ink);
}
.ref-card { display: flex; align-items: center; gap: 12px; }
.ref-card-thumb { inline-size: 72px; block-size: auto; border-radius: 8px; flex-shrink: 0; }
.ref-card-title { font-weight: 700; font-size: 14.5px; line-height: 1.7; }

/* Resource rows: kind icon in the category tile, title over a quiet meta line
   (kind · domain), external-link mark at the inline-end. */
.resource-list {
  list-style: none;
  padding-inline-start: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
  gap: 10px;
}
.resource-list > li { margin: 0; }
.resource-card {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 100%;
  padding: 10px 14px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--ink);
  transition: border-color 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;
}
a.resource-card:hover {
  color: var(--ink);
  border-color: var(--c-chip);
  background: var(--c-wash);
  box-shadow: 0 8px 18px var(--c-shadow);
}
.resource-icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--c-tile);
  color: var(--type-color);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.resource-icon svg { width: 17px; height: 17px; }
/* Featured image of the linked page, in the same leading slot as the icon
   tile. F105/F194: EVERY link thumbnail renders square (1:1, CSS crop) —
   external resources match the FaraDars rows; row height stays text-driven. */
.resource-thumb {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  object-fit: cover;
  background: var(--c-tile);
  flex: none;
}
.resource-text { flex: 1; min-width: 0; }
.resource-card-title {
  display: block;
  font-weight: 700;
  font-size: 14.5px;
  line-height: 1.7;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
a.resource-card:hover .resource-card-title { color: var(--type-color); }
.resource-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  line-height: 1.7;
  color: var(--ink-3);
  min-width: 0;
}
.resource-meta > * + *::before { content: '·'; margin-inline-end: 6px; color: var(--ink-4); }
.resource-kind { flex: none; }
.resource-domain { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; letter-spacing: 0.01em; }
.resource-ext-icon {
  inline-size: 15px;
  block-size: 15px;
  flex: none;
  color: var(--ink-4);
  transition: color 0.18s ease;
}
a.resource-card:hover .resource-ext-icon { color: var(--type-color); }

/* --- Badges ---------------------------------------------------------------- */

.badges { display: flex; flex-wrap: wrap; gap: 8px; margin-block-end: 14px; }
.badges:last-child { margin-block-end: 0; }
.badges + .badges { margin-block-start: -6px; }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 800;
  line-height: 1.8;
  padding: 3px 12px;
  border-radius: 999px;
  background: var(--c-tile);
  color: var(--type-color);
  max-width: 100%;
}
.badge-icon { width: 0.95em; height: 0.95em; flex: none; }
/* F183: the icon a linkified raw URL carries (lib/html.ts linkifyUrls via
   the `linkify` filter) — trails the compact host text inside prose. */
.linkified-ext-icon { width: 0.8em; height: 0.8em; vertical-align: -0.08em; margin-inline-start: 4px; }

.badge-neutral { background: var(--sand); color: var(--ink-2); }

/* Tiered scales run low → high; the hue carries the meaning (v3 families:
   green / blue / terracotta working accents on their tile tints). */
.badge-tone-good { background: #d1f1e3; color: #16775a; }
.badge-tone-mid { background: #d2ecff; color: #1a6d9e; }
.badge-tone-attn { background: #ffe0d7; color: #a74932; }
a.badge-tone-good:hover { color: #066148; }
a.badge-tone-mid:hover { color: #0c5983; }
a.badge-tone-attn:hover { color: #8b3925; }

.badge-outline { background: transparent; color: var(--ink-3); border: 1px solid var(--line-strong); font-weight: 700; }

a.badge { transition: color 0.18s ease, background-color 0.18s ease; }
a.badge:hover { color: var(--c-dark); }

.badge-link {
  background: var(--surface);
  border: 1px solid var(--c-chip);
  color: var(--type-color);
  font-weight: 700;
  transition: border-color 0.18s ease;
}
.badge-link:hover { border-color: var(--type-color); color: var(--type-color); }

.badge-hours { background: var(--c-tile); color: var(--type-color); }

/* CategoryChip on search rows & suggest items — a flat tile pill, no dot. */
.badge-type {
  background: var(--c-tile);
  color: var(--type-color);
  font-size: 11.5px;
  padding: 2px 10px;
  flex: none;
}

/* --- Search page ------------------------------------------------------------ */

.search-head .container { padding-block: 26px; }
.search-head h1 { font-size: 26px; letter-spacing: -0.01em; margin: 0; }

/* F153: buttonless sidebar query box — Enter submits. The decorative
   magnifier is PREPENDED at the inline START (physical RIGHT on this RTL
   site); the functional ✕ is APPENDED at the inline end — the two never
   share a corner. The input's own WebKit cancel button is suppressed (it
   rendered at the same end as the ✕ and collided with it). */
.search-box { position: relative; }
.search-box input[type='search'] { padding-inline-start: 40px; padding-inline-end: 38px; }
.search-box input[type='search']::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.search-box-icon {
  position: absolute;
  inset-inline-start: 13px;
  inset-block-start: 50%;
  translate: 0 -50%;
  display: inline-flex;
  color: var(--ink-4);
  pointer-events: none;
}
.search-box-icon svg { width: 16px; height: 16px; }
/* The ✕ clears the query and keeps the filter state (explore sidebar);
   hover turns red — it reads as the small destructive action it is. */
.search-box-clear {
  position: absolute;
  inset-inline-end: 13px;
  inset-block-start: 50%;
  translate: 0 -50%;
  display: inline-flex;
  padding: 4px;
  color: var(--ink-3);
  transition: color 0.18s ease;
}
.search-box-clear:hover { color: #b3261e; }
.search-box-clear svg { width: 14px; height: 14px; }
/* (The search-meta count LINE retired 2026-08-03 — the state-driven h1
   names the query/scope; the same day's UI audit (C1) put the total back as
   the shared F127 count-chip beside the h1, matching the static listing
   heads. FilterTabs retired with F132 — the type facet lives in the shared
   filter sidebar as multi-select pills.) */

/* F129: secondary clear-query action under the primary clear-all. */
.filter-clear-query {
  display: inline-flex;
  align-items: center;
  margin-block-start: 8px;
  align-self: flex-start;
  color: var(--ink-3);
  font-size: 12.5px;
  font-weight: 700;
  transition: color 0.18s ease;
}
.filter-clear-query:hover { color: var(--ink); }

/* F132: pagination centers under the RESULTS column (search + listings). */
.listing-main .pager { justify-content: center; }
.listing-main .pager, .listing-main .search-pagination { margin-block-end: 8px; }

/* F145: even container inset all around; each row is ONE flex line — chip ·
   stacked text · chevron — with the chevron centered against the whole row.
   Rows breathe around the hairline: 4px padding + 4px margin on each side of
   every separator, so the rounded hover highlight floats clear of the lines
   instead of touching them; the highlight itself is the row type's wash tint
   (data-cat family), not a flat neutral. */
.search-results {
  list-style: none;
  padding: 8px;
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
}
.search-result { margin: 0; }
.search-result + .search-result {
  margin-block-start: 4px;
  padding-block-start: 4px;
  border-block-start: 1px solid var(--line-soft);
}
.search-result-link {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px;
  border-radius: 12px;
  color: inherit;
  transition: background-color 0.15s ease;
}
.search-result-link:hover { background: var(--c-wash); color: inherit; }
.search-result-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* F132: quieter row — the chip identifies, the title carries, the snippet
   stays plain text (no highlight fragments). */
.search-result-title { font-size: 15.5px; font-weight: 700; color: var(--ink); line-height: 1.6; }
.search-result-chevron { width: 13px; height: 13px; flex: none; color: var(--chev); }
.search-snippet {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0;
  color: var(--ink-3);
  font-size: 13.5px;
  line-height: 1.8;
  max-width: 920px;
}

/* Empty state — always offers a next step. */
.empty-state {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 36px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  text-align: center;
}
.empty-icon {
  width: 58px;
  height: 58px;
  border-radius: 50%;
  background: var(--sand);
  color: var(--ink-4);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.empty-icon svg { width: 24px; height: 24px; }
.empty-title { font-size: 17.5px; font-weight: 800; color: var(--ink); }
.empty-body { font-size: 14px; color: var(--ink-3); max-width: 420px; line-height: 1.85; }
.empty-links { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center; margin-block-start: 6px; }
.empty-links-label { font-size: 13px; color: var(--ink-3); }
.empty-links a {
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 13.5px;
  color: var(--ink-body);
  transition: color 0.18s ease, border-color 0.18s ease;
}
.empty-links a:hover { border-color: var(--type-color); color: var(--type-color); }

/* --- Search suggest dropdown (site.js) -------------------------------------- */

/* F128: a proper suggestion PANEL — wider than its input when the viewport
   allows (site.js clamps it inside the viewport), quiet separated rows,
   scrolling list, full-width footer action. Anchored at the input's
   inline-start edge and growing toward inline-end. */
.search-suggest {
  position: absolute;
  inset-block-start: calc(100% + 10px);
  inset-inline-start: 0;
  width: min(33rem, calc(100vw - 24px));
  min-width: 100%;
  z-index: 60; /* F148: above result lists and sticky chrome */
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 16px;
  box-shadow: 0 28px 60px rgba(36, 35, 33, 0.14);
  padding: 8px;
}
@media (max-width: 48rem) {
  /* Phones (and the filter drawer): span the form — the form itself is
     near-full-width there. */
  .search-suggest { width: 100%; }
}
.search-suggest ul { list-style: none; margin: 0; padding: 0; max-height: min(24rem, 60vh); overflow-y: auto; }
.search-suggest li { margin: 0; }

.suggest-item a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 12px;
  border-radius: 11px;
  color: var(--ink);
  transition: background-color 0.15s ease;
}
.suggest-item a:hover, .suggest-item a.active { background: var(--c-wash); color: var(--ink); }
/* Hairline separators between rows (F128) — cheap to scan. */
.suggest-item + .suggest-item a { border-start-start-radius: 0; border-start-end-radius: 0; }
.suggest-item + .suggest-item { border-block-start: 1px solid var(--line-soft); }

/* The Persian type badge leads the row (no icons, F128). */
.suggest-type { flex: none; }

.suggest-text { flex: 1; min-width: 0; }
.suggest-title {
  display: block;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.6;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.suggest-summary {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12.5px;
  line-height: 1.8;
  color: var(--ink-3);
}
.suggest-chevron { width: 12px; height: 12px; flex: none; color: var(--chev); }

.suggest-empty { padding: 12px 14px; color: var(--ink-3); font-size: 14px; }

.suggest-item .suggest-footer {
  display: flex;
  align-items: center;
  justify-content: center; /* F128: one clear, full-width closing action */
  gap: 8px;
  padding: 12px 14px 9px;
  margin-block-start: 6px;
  border-block-start: 1px solid var(--line);
  border-radius: 0 0 10px 10px;
  color: var(--brand);
  font-weight: 700;
  font-size: 14px;
  transition: background-color 0.15s ease;
}
.suggest-item .suggest-footer:hover, .suggest-item .suggest-footer.active { background: var(--sand); color: var(--brand); }

/* --- Empty listing / generic states ---------------------------------------- */

.empty-note { color: var(--ink-3); text-align: center; padding-block: 40px; }

/* --- Error pages (404/410) --------------------------------------------------- */

.error-page {
  max-width: 560px;
  margin-inline: auto;
  text-align: center;
  padding-block: 56px 40px;
}
.error-code { font-size: 56px; font-weight: 800; color: var(--type-color); margin: 0; line-height: 1.2; }
.error-page h1 { font-size: 26px; margin-block: 8px 10px; }
.error-page p { color: var(--ink-3); }

/* --- Heading anchors (toc.js) ------------------------------------------------ */

.heading-anchor {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4em;
  height: 1.4em;
  margin-inline-start: 4px;
  vertical-align: middle;
  color: var(--ink-4);
  border-radius: 7px;
  opacity: 0;
  transition: opacity 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}
/* Inside the flex section heading the 12px gap already separates it — pull it
   back so the anchor sits right beside the text. */
.doc-section > h2 > .heading-anchor { margin-inline-start: -8px; }
.doc-section > h2:hover .heading-anchor,
.doc-section > h3:hover .heading-anchor,
.heading-anchor:focus-visible { opacity: 0.7; }
.heading-anchor:hover { opacity: 1; color: var(--type-color); background: var(--c-wash); }
.heading-anchor svg { width: 0.75em; height: 0.75em; }
.heading-anchor.copied { opacity: 1; color: var(--type-color); }
/* Hover tooltip: tells the reader the anchor copies the section link.
   Pure CSS (::after over the anchor), so it needs no JS and never blocks
   the click. Hidden again while .copied so it does not fight the feedback
   state, and suppressed on touch-only devices where hover is sticky. */
.heading-anchor { position: relative; }
.heading-anchor::after {
  content: 'کپی لینک این بخش';
  position: absolute;
  bottom: calc(100% + 7px);
  inset-inline-start: 50%;
  translate: 50% 0; /* RTL page: physical +x shift centers the bubble */
  background: var(--ink);
  color: var(--paper);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  padding: 6px 10px;
  border-radius: 7px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease 0.15s;
  z-index: 5;
}
.heading-anchor.copied::after { content: 'کپی شد!'; }
@media (hover: hover) {
  .heading-anchor:hover::after,
  .heading-anchor:focus-visible::after,
  .heading-anchor.copied::after { opacity: 1; visibility: visible; }
}

/* --- Return-to-top (site.js) -------------------------------------------------- */

.to-top {
  position: fixed;
  inset-block-end: 20px;
  inset-inline-end: 20px;
  z-index: 40;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-3);
  box-shadow: 0 6px 20px rgba(36, 35, 33, 0.12);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s 0.2s;
}
.to-top.visible { opacity: 1; visibility: visible; transform: none; transition: opacity 0.2s ease, transform 0.2s ease; }
.to-top:hover { border-color: var(--brand); color: var(--brand); }
.to-top svg { width: 20px; height: 20px; }

/* --- Generic field renderer leftovers ---------------------------------------- */

.field-row { margin-block: 0 0.5rem; }
.field-label { color: var(--ink-3); font-weight: 700; margin-inline-end: 0.25rem; }

.obj-group {
  border-inline-start: 3px solid var(--line-strong);
  padding-inline-start: 1rem;
  margin-block: 0.75rem 1rem;
}
.obj-group > :last-child { margin-block-end: 0; }

.swatch {
  display: inline-block;
  inline-size: 1em;
  block-size: 1em;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  vertical-align: -0.15em;
  margin-inline-end: 0.25rem;
}

.field-figure { margin: 0 0 1rem; }
.field-figure img { border-radius: 12px; display: block; }
.field-figure figcaption { color: var(--ink-3); font-size: 0.85rem; margin-block-start: 0.35rem; }
.field-video video { width: 100%; height: auto; border-radius: 12px; display: block; background: #000; }

.gallery { margin-block-end: 1rem; }
.gallery .field-figure { margin: 0; }
.gallery img { inline-size: 100%; object-fit: cover; }

.embed-frame { aspect-ratio: 16 / 9; margin-block-end: 1rem; border-radius: 12px; overflow: hidden; background: var(--ink); }
.embed-frame iframe { inline-size: 100%; block-size: 100%; border: 0; display: block; }
.embed-caption { color: var(--ink-3); font-size: 0.9rem; margin-block: -0.5rem 1rem; }

.field-file .file-link { font-weight: 700; color: var(--brand); }
.file-size { color: var(--ink-3); font-size: 0.85rem; }

/* Unified content patterns ------------------------------------------------ */

/* Authored tables (F159) — bordered, tinted header, zebra body, in the same
   soft-rounded language as the rest of the system. The .table-scroll wrapper
   is added at render time (wrap_tables filter) so a wide table scrolls
   inside its own box instead of clipping or panning the page. */
.table-scroll {
  margin: 18px 0;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface);
}
.richtext table {
  width: 100%;
  margin: 0;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
  line-height: 1.85;
}
.richtext th,
.richtext td {
  padding: 10px 14px;
  text-align: start;
  vertical-align: top;
  min-width: 9rem;
  border-block-start: 1px solid var(--line-soft);
}
.richtext th + th,
.richtext td + td { border-inline-start: 1px solid var(--line-soft); }
/* Header row: the type's tile tint — the same accent family the page wears. */
.richtext thead th {
  background: var(--c-tile);
  color: var(--c-dark);
  font-weight: 700;
  border-block-start: 0;
  white-space: nowrap;
}
.richtext tbody tr:first-child > * { border-block-start: 0; }
.richtext thead + tbody tr:first-child > * { border-block-start: 1px solid var(--line-soft); }
/* Zebra rows keep long comparison tables scannable. */
.richtext tbody tr:nth-child(even) { background: var(--c-wash); }
.richtext td p, .richtext th p { margin: 0; }

/* A plain emphasis box, not a quotation — flat solid background, one plain
   border, no accent bar, no shadow, no quote mark. */
.richtext blockquote {
  margin: 20px 0;
  padding: 16px 20px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 14px;
  color: var(--ink-body);
}
.richtext blockquote > :last-child { margin-block-end: 0; }

.checklist { gap: 10px; }
.checklist li {
  padding: 12px 46px 12px 16px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 14px;
}
.checklist li::before {
  inset-inline-start: 14px;
  inset-block-start: 13px;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border-radius: 7px;
  background: var(--c-tile);
  font-size: 13px;
}

.doc-section > .relation-rows + .prereq-list,
.doc-section > .relation-rows + .badges { margin-block-start: 26px; }

.learning-path-unified { gap: 22px; }
.learning-path-unified .learning-step {
  position: relative;
  padding: 0;
  padding-inline-start: 58px;
  background: transparent;
  border: 0;
  border-radius: 0;
}
.learning-path-unified .learning-step::before { content: none; display: none; }
.learning-path-unified .learning-step::after {
  inset-inline-start: 19px;
  inset-block-start: 58px;
  inset-block-end: -28px;
  width: 2px;
  background: var(--c-border);
}
/* The circled number is the ONLY step indicator — no repeated "step N" text
   alongside it, and no shadow at rest (flat, in line with the rest of the
   system); only a plain ring keeps it legible against the card edge. */
.learning-step-marker {
  position: absolute;
  z-index: 2;
  inset-inline-start: 0;
  inset-block-start: 17px;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: 4px solid var(--paper);
  border-radius: 50%;
  background: var(--type-color);
  color: var(--c-on);
  box-shadow: 0 0 0 3px var(--c-panel);
  font-size: 14px;
  font-weight: 900;
  line-height: 1;
}
.learning-step-card {
  overflow: hidden;
  border: 1px solid var(--c-border);
  border-radius: 20px;
  background: var(--surface);
  transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.learning-step-card:hover {
  border-color: var(--c-chip);
  box-shadow: 0 8px 20px var(--c-shadow);
  transform: translateY(-2px);
}
.learning-step-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 20px 14px;
  border-block-end: 1px solid var(--c-border);
}
.learning-step-heading { min-width: 0; }
.learning-path-unified .learning-step h3,
.learning-path-unified .learning-step h4 {
  margin: 0;
  color: var(--ink);
  font-size: 17px;
  font-weight: 900;
  line-height: 1.55;
}
.learning-step-time {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  flex: none;
  padding: 5px 11px;
  border: 1px solid var(--c-border);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink-3);
  font-size: 12px;
  white-space: nowrap;
}
.learning-step-content { padding: 16px 20px 18px; }
.learning-step-content > :first-child { margin-block-start: 0; }
.learning-step-content > :last-child { margin-block-end: 0; }
.learning-step-content .richtext { color: var(--ink-body); }
.learning-step-content .field-mini-label {
  margin-block: 14px 5px;
  color: var(--ink-2);
  font-size: 12.5px;
}
.learning-step-content .relation-pills { margin-block: 4px 10px; }

.relation-pills { display: flex; flex-wrap: wrap; gap: 7px; margin-block: 8px 12px; }
.relation-pill {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 3px 10px;
  border: 1px solid var(--c-border);
  border-radius: 999px;
  background: var(--c-tile);
  color: var(--type-color);
  font-size: 12.5px;
  font-weight: 800;
}
.relation-pill:hover { background: var(--c-panel); color: var(--c-dark); }

/* F79: inside the learning rail, pills and badges go OUTLINE — a step that
   lists many skills/tools turns filled tiles into a wall of color that
   competes with the content. */
.learning-path-unified .relation-pill,
.learning-path-unified .badge {
  background: transparent;
  border: 1px solid var(--c-chip);
  color: var(--type-color);
}
.learning-path-unified .relation-pill:hover { background: var(--c-tile); color: var(--c-dark); }
.learning-path-unified .learning-step-time { background: transparent; }

.direct-relation-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border: 1px solid var(--c-border);
  border-radius: 999px;
  background: var(--c-tile);
  /* Size inherits the sidebar value tier via .glance-value (--sb-value). */
  font-weight: 800;
  transition: border-color 0.18s ease;
}
/* Beats `.glance-value a { color: var(--brand) }` (two classes vs one) so the
   pill keeps its own type's accent at rest instead of falling back to the
   brand link blue. */
.glance-value .direct-relation-pill,
.glance-value .direct-relation-pill:hover { color: var(--type-color); }
.glance-value .direct-relation-pill:hover { border-color: var(--type-color); }
.direct-relation-pill-icon { width: 14px; height: 14px; flex: none; }
/* Same fix, same reason: a linked multiselect glance badge (categories, T:
   category taxonomy) is an `<a>` too, so `.glance-value a { color: var(--brand) }`
   otherwise wins over `.badge-link`'s own color at rest (equal class count,
   but the plain rule's trailing element selector loses on source order only
   AFTER a class-count tie — `.glance-value .badge-link` has one more class,
   so it wins outright). Without this the pill's text renders generic brand
   blue instead of its type's accent. */
.glance-value .badge-link,
.glance-value .badge-link:hover { color: var(--type-color); }
/* F163 (supersedes the one-per-line rule): tag lists ride the shared label
   line and wrap; the wider column gap keeps distinct values scannable. */
.glance-badges { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 12px; row-gap: 4px; }

@media (max-width: 36rem) {
  .learning-path-unified .learning-step { padding-inline-start: 48px; }
  .learning-step-marker { width: 34px; height: 34px; inset-block-start: 18px; border-width: 3px; }
  .learning-path-unified .learning-step::after { inset-inline-start: 16px; inset-block-start: 55px; }
  .learning-step-header { align-items: flex-start; flex-direction: column; gap: 9px; }
  .learning-step-time { align-self: flex-start; }
  .learning-path-total { padding-inline-start: 48px; }
  .learning-path-total .learning-step-marker { inset-block-start: 14px; }
}

.item-list-routes { gap: 14px; }
.item-list-routes .item {
  padding: 18px 20px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 16px;
}
.item-list-routes .item::before { display: none; }
.item-list-routes .field-labeled:last-child {
  display: inline-flex;
  margin-block-start: 8px;
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--c-tile);
  color: var(--c-dark);
  font-size: 12.5px;
}

.item-list-questions .item {
  padding: 18px 20px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 16px;
}
.item-list-questions .item::before { display: none; }
.item-list-questions .fact { inline-size: fit-content; margin-block-end: 12px; }
.item-list-questions .field-mini-label {
  margin-block: 14px 5px;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 800;
}
.item-list-questions .field-key-answer-guidance,
.item-list-questions .field-key-model-answer {
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
}
.item-list-questions .field-key-model-answer {
  border-color: var(--c-border);
  background: var(--c-wash);
}
.legacy-question-list > ul {
  display: grid;
  gap: 9px;
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}
.legacy-question-list > ul > li {
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
}
.legacy-question-list > ul > li::before { display: none; }
.legacy-question-list em {
  display: block;
  margin-block-start: 8px;
  color: var(--ink-3);
  font-style: normal;
}

/* Interview question cards: category → question → short caption stay in
   view; the longer answer guidance / model answer fold into a native
   <details> disclosure so a list of questions doesn't read as a wall of
   text. Flat, no resting shadow. */
.qa-list { list-style: none; padding-inline-start: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; }
.qa-item { padding: 16px 18px; background: var(--paper); border: 1px solid var(--line); border-radius: 14px; }
.qa-item-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* F85: the category is orientation, not content — outline + muted so the
   question itself carries the row. */
.qa-category {
  flex: none;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink-3);
  font-weight: 600;
}
.qa-question { flex: 1; min-width: 0; margin: 0; font-size: 15.5px; font-weight: 800; color: var(--ink); line-height: 1.7; }
.qa-caption { margin: 6px 0 0; font-size: 13.5px; color: var(--ink-3); line-height: 1.8; }
/* The toggle is an ACTION (expand/collapse), so it takes the brand action
   color, not the page's category accent (v3: category color = what you're
   looking at, brand blue = what you can do). */
.qa-details { margin-block-start: 10px; }
.qa-details summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  list-style: none;
  cursor: pointer;
  padding: 4px 2px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--brand);
}
.qa-details summary:hover { color: var(--brand-dark); }
.qa-details summary::-webkit-details-marker { display: none; }
.qa-details summary::before {
  content: '';
  width: 7px;
  height: 7px;
  flex: none;
  border-inline-end: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 0.18s ease;
}
.qa-details[open] summary::before { transform: rotate(45deg); }
.qa-details-body { margin-block-start: 8px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; }
/* Accordion parts (answer guidance / model answer) carry no mini-labels —
   the <summary> names them (T10); a hairline separates the two. */
.qa-detail-part + .qa-detail-part {
  border-block-start: 1px solid var(--line-soft);
  margin-block-start: 12px;
  padding-block-start: 12px;
}
/* Question level badge (T9) — neutral, so the colored category badge stays
   the primary scent. */

/* FAQ accordion (T16): reuses the qa-details disclosure (chevron caret,
   hidden marker, folding body). Unlike the qa toggle, the summary here IS
   the question — content, not an action — so it reads ink-colored at body
   size and only takes the brand color on hover/open. */
.faq-list { display: flex; flex-direction: column; gap: 10px; }
.faq-item.qa-details { margin-block-start: 0; background: var(--paper); border: 1px solid var(--line); border-radius: 14px; }
.faq-item summary { display: flex; width: 100%; padding: 12px 16px; font-size: 15px; color: var(--ink); }
/* F97: the caret sits at the inline-end (LEFT in RTL) of the FAQ header —
   the question reads first, the affordance closes the row. */
.faq-item summary::before { order: 2; margin-inline-start: auto; }
.faq-item summary:hover, .faq-item[open] summary { color: var(--brand); }
.faq-item .qa-details-body { margin: 0 16px 14px; }
.faq-item .qa-details-body p { margin: 0; line-height: 1.9; }

/* External resources deliberately use one neutral visual family. */
.resource-card, .ref-card { --resource-accent: #626872; }
.resource-icon { background: #eef0f2; color: var(--resource-accent); }
a.resource-card:hover, a.ref-card:hover { border-color: #aeb3ba; background: #f7f7f6; box-shadow: 0 8px 18px rgba(31, 36, 48, 0.08); }
a.resource-card:hover .resource-card-title,
a.resource-card:hover .resource-ext-icon { color: var(--resource-accent); }

/* Static (URL-less) resource entries carry no click affordance, so they must
   not wear the same solid card chrome as a real link — a dashed, unfilled
   treatment signals "reference only" before a reader tries to click it. */
.resource-card-static { border-style: dashed; background: transparent; }
.resource-card-static .resource-icon { background: transparent; color: var(--ink-3); border: 1px solid var(--line); }

.related-filters { display: flex; flex-wrap: wrap; gap: 7px; margin-block-end: 14px; }
.related-filter {
  appearance: none;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink-3);
  padding: 5px 12px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.related-filter:hover { border-color: var(--ink-3); color: var(--ink); }
.related-filter.active { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.related-items-list > li[hidden],
.resource-list > li[hidden],
.faradars-list > li[hidden] { display: none; }

/* «نمایش بیشتر…» ↔ «نمایش کمتر» under collapsible lists (F104, toc.js).
   Quiet-chip look; the chevron flips while expanded (disclosure contract). */
.list-more-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-block-start: 12px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 700;
  background: var(--surface);
  border: 1px solid var(--c-chip);
  padding: 7px 15px;
  border-radius: 999px;
  color: var(--type-color);
  cursor: pointer;
  transition: border-color 0.18s ease;
}
.list-more-btn:hover { border-color: var(--type-color); }
.list-more-chevron { display: inline-flex; }
.list-more-chevron svg { width: 13px; height: 13px; transition: transform 0.18s ease; }
.list-more-btn.expanded .list-more-chevron svg { transform: rotate(180deg); }

.doc-tag-list { display: flex; flex-wrap: wrap; gap: 7px; }
.doc-tag {
  padding: 3px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink-3);
  font-size: 12px;
}
.doc-tag:hover { border-color: var(--line-strong); color: var(--ink); }

/* --- Motion & responsiveness -------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .relation-card:hover, .cat-tile:hover, .relation-cards .relation-card:hover, .relation-row:hover { transform: none; }
}

/* Floating sidebar button (site.js): phone-only (the 63.99rem block below
   turns it on — this base rule must stay ABOVE that block so the media rule
   wins, F140), accent-filled, above the drawer so it doubles as its close
   toggle. Sits at the inline-START edge — the physical RIGHT on this RTL
   site — leaving the to-top button its inline-end corner. */
.sidebar-fab {
  display: none;
  position: fixed;
  z-index: 56;
  inset-block-end: 20px;
  inset-inline-start: 20px;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: none;
  border-radius: 999px;
  background: var(--type-color, var(--brand));
  color: var(--c-on, #fff);
  box-shadow: 0 8px 24px rgba(36, 35, 33, 0.3);
  cursor: pointer;
}
.sidebar-fab svg { width: 22px; height: 22px; }
/* Active-filter count badge on the drawer button (F131) — site.js copies it
   from the sidebar's data-active-filters attribute. */
.sidebar-fab-count {
  position: absolute;
  inset-block-start: -4px;
  inset-inline-end: -4px;
  min-width: 20px;
  height: 20px;
  padding-inline: 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--ink);
  color: var(--paper);
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1;
}

/* Must complement the sticky-sidebar query above (min-width: 64rem) exactly —
   an overlap would leave the STACKED sidebar sticky and viewport-capped. */
@media (max-width: 63.99rem) {
  .doc-layout { grid-template-columns: 1fr; gap: 18px; }
  /* Content before chrome: on phones/tablets the article renders first and
     the at-a-glance/TOC sidebar follows, instead of forcing a scroll past
     both cards before any real content appears. (No-JS fallback — with JS
     the sidebar folds into the drawer below instead.) */
  .doc-layout > .doc-sidebar { order: 2; }
  .doc-layout > .doc { order: 1; }

  /* F101/F108: with site.js present (body.sidebar-collapsible) the sidebar
     leaves the flow entirely and opens as a bottom-sheet drawer from the
     floating button. */
  body.sidebar-collapsible .doc-layout > .doc-sidebar { display: none; }
  body.sidebar-collapsible.sidebar-open .doc-layout > .doc-sidebar {
    display: flex;
    position: fixed;
    z-index: 55;
    inset-inline: 0;
    inset-block-end: 0;
    max-height: 78dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
    margin: 0;
    background: var(--paper);
    border-block-start: 1px solid var(--line-strong);
    border-start-start-radius: 20px;
    border-start-end-radius: 20px;
    /* Bottom clearance = FAB footprint (20px inset + 48px button + breathing
       room): the floating button stays visible over the open sheet and used
       to sit ON the sheet's last row (last filter group / last TOC entry). */
    padding: 16px 16px calc(84px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -18px 50px rgba(36, 35, 33, 0.28);
  }
  body.sidebar-open { overflow: hidden; }
  /* AFTER the base rule below in the cascade? No — media rules must WIN, so
     the base .sidebar-fab { display:none } is authored ABOVE this block.
     (F140: it originally sat below and the button never appeared.) */
  .sidebar-fab { display: inline-flex; }
}
.sidebar-backdrop {
  position: fixed;
  inset: 0;
  z-index: 54;
  background: rgba(36, 35, 33, 0.45);
}
.sidebar-backdrop[hidden] { display: none; }

@media (max-width: 48rem) {
  .container, .site-header .container { padding-inline: 20px; }
  h1 { font-size: 1.75rem; }
  .doc-head h1.doc-title { font-size: 1.6rem; }
  .hero h1 { font-size: 1.85rem; }
  .listing-head h1 { font-size: 1.75rem; }
  .hero .container { padding-block: 30px 26px; }
  .category-panel { padding: 18px; border-radius: 20px; }
  .doc-section { padding: 18px 20px 20px; border-radius: 18px; }
  .relation-row { gap: 12px; padding: 12px 14px; border-radius: 14px; }
  .relation-row-icon { width: 38px; height: 38px; border-radius: 11px; }
  .relation-row-icon svg { width: 19px; height: 19px; }
  .relation-row-title { font-size: 15px; }
  .site-nav { order: 3; flex-basis: 100%; margin-inline-start: 0; }
  .listing-icon { width: 44px; height: 44px; }
  .listing-icon svg { width: 23px; height: 23px; }
}

/* --- Touch ergonomics ---------------------------------------------------- */

@media (pointer: coarse) {
  /* iOS Safari zooms the page onto any focused input under 16px; the sidebar
     boxes were 14.5px (the hero was already 16px). Desktop keeps its denser
     size — this only follows the primary coarse pointer. */
  .listing-tools .search-form input[type='search'] { font-size: 16px; }
  /* Small inline links that double as primary navigation on phones
     (breadcrumbs, sidebar utility links): grow the tap slab without moving
     a pixel of layout (padding paid back by margin). */
  .crumbs a,
  .filter-clear-query,
  .filters-reset {
    padding-block: 8px;
    margin-block: -8px;
  }
}
