/* spritz frontend: "dark premium store" look.
   WebPositive-safe: linear-gradient, box-shadow, border-radius, inline-block
   grid. NO CSS grid, NO custom properties, NO modern-only selectors. */

* { box-sizing: border-box; }

html, body {
  /* Clip horizontal overflow at the page edge. The .hero band is full-bleed via
     a margin/padding of 9999px, which only stays contained if something hides the
     x-overflow; without this the page scrolls sideways to infinity. Also a safety
     net for any wide child (e.g. the featured carousel). */
  overflow-x: hidden;
}

body {
  margin: 0;
  font-family: "DejaVu Sans", Verdana, Arial, sans-serif;
  color: #1f2933;
  background: #eef2f7;
  line-height: 1.55;
  /* sticky footer: page fills the viewport, footer sits at the bottom even on
     short pages (like the 404), so the content does not look stranded. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
.content { flex: 1 0 auto; }

a { color: #2563eb; text-decoration: none; }
a:hover { text-decoration: underline; }

/* Visible keyboard focus everywhere (audit a11y): buttons, links, badges and the
   language picker had none, so tabbing was invisible. Cyan ring, WebPositive-safe. */
.btn:focus, .header-link:focus, a.badge:focus, .app-link:focus,
.lang-picker:focus, .cat-list a:focus, .brand:focus {
  outline: 2px solid #22d3ee; outline-offset: 2px;
}

/* ---------- Header: dark, gradient, cyan accent ---------- */
.site-header {
  display: flex;
  align-items: center;
  padding: 12px 24px;
  background: #0b1220;
  background: linear-gradient(90deg, #0b1220 0%, #16243d 100%);
  border-bottom: 2px solid #22d3ee;
  flex-wrap: wrap;
}
.brand {
  font-size: 22px;
  font-weight: bold;
  letter-spacing: 0.5px;
  color: #ffffff;
  margin-right: 18px;
}
.brand:hover { text-decoration: none; color: #22d3ee; }
.search-inline { margin-right: auto; }
.search-inline input {
  padding: 8px 12px;
  border: 1px solid #2b3a55;
  border-radius: 6px;
  background: #0e1a2e;
  color: #e8eef6;
  min-width: 200px;
}
.search-inline input::placeholder { color: #7b8aa3; }
.search-inline button {
  padding: 8px 14px; margin-left: 6px;
  border: 0; border-radius: 6px;
  background: #22d3ee; color: #06222a; font-weight: bold; cursor: pointer;
}
.search-inline button:hover { background: #67e8f9; }

/* The links live in one box so they wrap as a group. Loose in the header they
   were flex items of it, and on a narrow screen they broke apart one by one,
   dragging the language picker onto a line of its own. */
.header-nav { display: flex; align-items: center; flex-wrap: wrap; }
.header-link {
  color: #c7d2e0; font-size: 14px; margin-left: 14px; padding: 6px 2px;
}
.header-link:hover { color: #ffffff; text-decoration: none; }
.lang-picker {
  margin-left: 16px; font-size: 13px;
  padding: 6px 8px; border-radius: 6px;
  background: #0e1a2e; color: #e8eef6; border: 1px solid #2b3a55;
  cursor: pointer;
}
.lang-picker:hover { border-color: #22d3ee; }
/* options render with the OS widget; keep them readable on dark hosts */
.lang-picker option { background: #ffffff; color: #1f2933; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  padding: 9px 16px;
  border: 0; border-radius: 8px;
  background: #2563eb; color: #ffffff; font-size: 14px; font-weight: 600;
  cursor: pointer; text-decoration: none;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.25);
}
.btn:hover { background: #1d4ed8; text-decoration: none; }
.btn-fallback, .btn-bootstrap {
  background: #ffffff; color: #1f2d3d; border: 1px solid #cdd7e5;
  box-shadow: none;
}
.btn-fallback:hover, .btn-bootstrap:hover { background: #f1f5f9; }
.btn-deeplink { background: #16a34a; }
.btn-deeplink:hover { background: #15803d; }
.btn-danger { background: #dc2626; }
.btn-danger:hover { background: #b91c1c; }

/* The catalog grid can only be as wide as this box, so the cap decides the column
   count: at 1180px it was four, on every monitor, and a wide screen just grew the
   white margins. At 1560px a large display gets six and a laptop five, while the
   grid still steps down on its own as the window narrows. Prose is NOT allowed to
   follow it out here -- see .app-detail below -- because a 1500px line of text is
   unreadable. */
.content { max-width: 1560px; margin: 0 auto; padding: 0 20px 32px; }

/* ---------- Hero: dark band ---------- */
.hero {
  margin: 0 -9999px 24px;            /* full-bleed band */
  padding: 44px 9999px 40px;
  text-align: center;
  background: #0b1220;
  background: linear-gradient(160deg, #0b1220 0%, #1b2c4a 70%, #1e3a5f 100%);
  color: #e8eef6;
  border-bottom: 1px solid #0a1019;
}
.hero h1 { margin: 0 0 10px; font-size: 34px; color: #ffffff; font-weight: 800; }
.lead { color: #aab8cc; max-width: 620px; margin: 0 auto 22px; font-size: 17px; }
.search-big input {
  padding: 13px 16px; width: 60%; max-width: 440px;
  border: 0; border-radius: 8px 0 0 8px; font-size: 15px;
  background: #0e1a2e; color: #e8eef6; vertical-align: middle;
  border: 1px solid #2b3a55;
}
.search-big input::placeholder { color: #7b8aa3; }
.search-big button {
  padding: 14px 22px; border: 0; border-radius: 0 8px 8px 0; font-size: 15px;
  background: #22d3ee; color: #06222a; font-weight: bold; cursor: pointer;
  vertical-align: middle;
}
.search-big button:hover { background: #67e8f9; }

/* ---------- Section headings ---------- */
.results h2, .app-info h2, .screenshots h2, .install h2 {
  font-size: 19px; color: #0f172a; font-weight: 700;
  margin-top: 28px; margin-bottom: 4px;
}
.results h2 { border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; }

/* ---------- App grid ---------- */
/* Flexbox grid: whitespace between <li> is ignored (unlike inline-block, where
   it eats real width and bumps the 4th card to the next row).
   This is the fallback for browsers without CSS grid (WebPositive); the modern
   profile overrides it further down. It used to be `width: 23%`, which pins the
   row to four cards at ANY container width -- so widening .content produced four
   fat cards rather than more of them. A flex basis lets the row fit as many as
   the width allows and wrap the rest, which is the same behaviour grid gives,
   without grid. */
.app-list {
  list-style: none; padding: 0; margin: 16px 0;
  display: flex; flex-wrap: wrap;
}
.app-card {
  flex: 1 1 220px; max-width: 300px; min-width: 180px;
  margin: 0 1% 20px; box-sizing: border-box;
  background: #ffffff; border: 1px solid #e4e9f1; border-radius: 12px;
  padding: 18px; box-shadow: 0 2px 6px rgba(15, 23, 42, 0.06);
}
.app-card:hover { box-shadow: 0 6px 18px rgba(15, 23, 42, 0.13); border-color: #cdd7e5; }
.app-link { color: inherit; display: block; }
.app-link:hover { text-decoration: none; }
.app-link-row { display: block; }              /* grid card: icon on top */
.app-icon-sm {
  width: 56px; height: 56px; border-radius: 14px; margin-bottom: 10px;
  display: block; box-shadow: 0 1px 3px rgba(15, 23, 42, 0.15);
}
.app-icon-placeholder {
  width: 56px; height: 56px; border-radius: 14px; margin-bottom: 10px;
  background: linear-gradient(135deg, #2563eb 0%, #22d3ee 100%);
  color: #fff; font-size: 26px; font-weight: 800; text-align: center;
  line-height: 56px;
}
.app-name { font-size: 17px; font-weight: 700; color: #0f172a; display: block; }
.app-summary { display: block; color: #5b6b80; margin-top: 4px; font-size: 14px; min-height: 2.6em; }
.app-meta { margin-top: 12px; }

/* ---------- Badges ---------- */
.badge {
  display: inline-block; font-size: 12px; padding: 3px 9px; margin: 2px 5px 2px 0;
  border-radius: 999px; background: #eef2f7; border: 1px solid #e2e8f0; color: #475569;
}
.badge-channel { background: #e0f2fe; border-color: #bae6fd; color: #0369a1; }
.badge-bridge { background: #dcfce7; border-color: #bbf7d0; color: #15803d; }
/* Amber, not another blue: the architecture is the one badge that decides whether
   the app will run at all, so it should not read as just another tag. */
.badge-arch { background: #fef3c7; border-color: #fde68a; color: #92400e;
  font-family: "DejaVu Sans Mono", monospace; }
.badge-category { background: #ede9fe; border-color: #ddd6fe; color: #6d28d9; }
.badge-category:hover { background: #ddd6fe; text-decoration: none; }
/* The same icon as the category page, at badge size. vertical-align keeps it on
   the text's baseline instead of pushing the pill taller than its neighbours.
   No :has() to tighten the padding of the badges that have one -- this file is
   WebPositive-safe by rule (no modern-only selectors), and the icon's own margin
   is enough. */
.badge-category .badge-icon {
  width: 14px; height: 14px; vertical-align: -3px; margin-right: 4px;
}
a.badge-bacaro:hover { background: #e2e8f0; text-decoration: none; }
.empty { color: #64748b; font-style: italic; }
.curated-note { background: #eff6ff; border: 1px solid #dbeafe; border-radius: 8px;
  padding: 10px 14px; color: #1e40af; font-size: 14px; margin: 8px 0 16px; }
.badge-downloads { background: #fef3c7; border-color: #fde68a; color: #92400e; font-weight: 700; }
.badge-multi { background: #e0e7ff; border-color: #c7d2fe; color: #4338ca; font-weight: 600; }

/* ---------- Library ("My apps") state pills + card actions ---------- */
/* State-specific colours so the queue state reads at a glance, instead of the
   recycled green bridge badge. */
.badge-state { font-weight: 600; }
.badge-state-pending   { background: #fef3c7; border-color: #fde68a; color: #92400e; }  /* queued: amber */
.badge-state-installed { background: #dcfce7; border-color: #bbf7d0; color: #15803d; }  /* installed: green */
.badge-state-removed   { background: #f1f5f9; border-color: #e2e8f0; color: #64748b; }  /* removed: grey */
.badge-state-unavailable { background: #fee2e2; border-color: #fecaca; color: #b91c1c; }
/* Remove button sits on its own row under the meta, not crowding the badges. */
.lib-card .lib-actions { margin-top: 12px; padding-top: 10px; border-top: 1px solid #eef2f7; }
.lib-card .btn-remove { padding: 5px 12px; font-size: 13px; }
.lib-card .btn-remove:hover { background: #fee2e2; border-color: #fca5a5; color: #b91c1c; }

/* Two-column layout: library on the left, a "most downloaded" card on the right.
   Flex row (WebPositive-safe); the right column has a fixed-ish width. */
/* A card. The library page used to be one big .app-detail with everything inside
   it, so "my apps" and "most downloaded this month" read as parts of the same
   box -- and they are not: one is yours, the other is everyone's. Same surface as
   .app-detail, without its prose width cap. */
.card {
  background: #ffffff; border: 1px solid #e4e9f1; border-radius: 14px;
  padding: 20px 22px; margin: 0 0 18px;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.05);
}
.card:last-child { margin-bottom: 0; }
/* A card carries its own name and the sentence that says what it is for: it is a
   section, not a slab. */
.card-title { margin: 0 0 4px; font-size: 22px; color: #0f172a; font-weight: 700; }
.card-lead { color: #5b6b80; margin: 0 0 14px; font-size: 15px; }

/* Two thirds and one third, not "everything left over" and a fixed 300px: the
   shelf is a column of the page, so it grows with the page instead of leaving a
   wider and wider library beside a strip that never changes. flex-basis in
   percent (no CSS grid: WebPositive). */
.lib-page { margin-top: 24px; }
.lib-layout { display: flex; flex-wrap: wrap; align-items: flex-start; }
.lib-main { flex: 1 1 64%; min-width: 0; margin-right: 2%; }
.lib-side { flex: 1 1 32%; min-width: 260px; max-width: none; }
/* Compact vertical list for the sidebar (not the 4-up card grid). */
.side-list { list-style: none; padding: 0; margin: 8px 0 0; }
.side-list li { border-bottom: 1px solid #eef2f7; }
.side-list li:last-child { border-bottom: 0; }
.side-item { display: flex; align-items: center; padding: 10px 4px; color: inherit; }
.side-item:hover { text-decoration: none; }
.side-icon { width: 36px; height: 36px; border-radius: 9px; margin-right: 12px;
  flex-shrink: 0; box-shadow: 0 1px 3px rgba(15,23,42,0.15); }
.side-text { flex: 1 1 auto; min-width: 0; display: flex; align-items: center;
  justify-content: space-between; }
.side-name { font-size: 14px; font-weight: 600; color: #0f172a; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; margin-right: 8px; }
/* On narrow screens the sidebar drops below the library, full width. */
@media (max-width: 720px) {
  .lib-main { margin-right: 0; }
  .lib-side { flex: 1 1 100%; max-width: none; margin-top: 20px; }
}

/* ---------- "Available also in" (same app, multiple repos) ---------- */
.also-in .source-list { list-style: none; padding: 0; margin: 10px 0 0; }
.also-in .source-list li { padding: 8px 0; border-bottom: 1px solid #eef2f7; }
.also-in .source-list li:last-child { border-bottom: 0; }
.also-in .source-list .badge { margin-left: 8px; }
.badge-newest { background: #16a34a; border-color: #15803d; color: #ffffff; font-weight: 700; }
.latest-note { font-size: 14px; color: #92400e; background: #fffbeb; border: 1px solid #fde68a;
  border-radius: 8px; padding: 8px 12px; margin: 4px 0 12px; }
.latest-note.latest-here { color: #065f46; background: #ecfdf5; border-color: #a7f3d0; }

/* ---------- Home shelves (featured / top / from-repos) ---------- */
.shelf-title { font-size: 19px; color: #0f172a; font-weight: 700;
  margin: 30px 0 4px; border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; }
.featured { margin-top: 8px; }
.featured-card {
  display: flex; align-items: center; color: inherit;
  background: #ffffff; border: 1px solid #e4e9f1; border-radius: 14px;
  padding: 22px 26px; margin-top: 14px;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.06);
  border-left: 5px solid #22d3ee;
}
.featured-card:hover { text-decoration: none; box-shadow: 0 8px 22px rgba(15,23,42,0.14); }
.featured-icon { width: 84px; height: 84px; border-radius: 20px; margin-right: 22px;
  box-shadow: 0 2px 6px rgba(15,23,42,0.18); flex-shrink: 0; }
.featured-body { flex: 1 1 auto; }
.featured-name { display: block; font-size: 22px; font-weight: 800; color: #0f172a; }
.featured-summary { display: block; color: #5b6b80; margin: 4px 0 8px; font-size: 15px; }
.featured-meta .badge { margin-top: 2px; }
.featured-cta { margin-left: 22px; flex-shrink: 0; }

/* --- featured carousel (lite-safe baseline) --- */
.featured-carousel { display: flex; align-items: center; margin-top: 14px; }
.featured-track {
  /* A horizontal row of cards. Lite (WebPositive) shows two at a time via JS
     display toggling; the row itself does not need to scroll there.
     min-width:0 is essential: without it this flex child grows to fit ALL its
     cards side by side (4 x 49% ~= 2x the page) and pushes the whole page wider,
     giving an endless horizontal scroll. min-width:0 lets it shrink to the
     carousel and clip the overflow instead. */
  display: flex; flex: 1 1 auto; min-width: 0; overflow: hidden;
}
.featured-carousel .featured-card {
  /* Two cards side by side: each ~half the track minus the gap. margin-top is
     reset because the carousel container already spaces the section. */
  flex: 0 0 48%; width: 48%; margin-top: 0; margin-right: 2%; box-sizing: border-box;
}
.featured-carousel .featured-card:last-child { margin-right: 0; }
.featured-nav {
  flex: 0 0 auto; width: 34px; height: 34px; margin: 0 6px;
  border: 1px solid #cdd7e5; background: #ffffff; color: #334155;
  border-radius: 50%; font-size: 20px; line-height: 1; cursor: pointer;
}
.featured-nav:hover { background: #f1f5f9; border-color: #94a3b8; }
.featured-nav[disabled] { opacity: 0.4; cursor: default; }

/* ---------- Pager ---------- */
/* flex `gap` only shipped in WebKit 14.1, newer than WebPositive's fork, so it
   collapses to zero spacing there. Use per-child margins instead (the rest of
   this file already does), keeping the "no modern-only CSS" promise. */
.pager { margin: 8px 0 18px; display: flex; align-items: center; }
.pager > * { margin-right: 12px; }
.pager > *:last-child { margin-right: 0; }
.pager-info { color: #64748b; font-size: 14px; }

/* ---------- Categories page ---------- */
.cat-list { list-style: none; padding: 0; margin: 18px 0; }
.cat-list li { display: inline-block; margin: 4px 6px 4px 0; }
.cat-list .badge-category { font-size: 14px; padding: 7px 14px; }
.cat-count { color: #8b5cf6; font-weight: bold; margin-left: 5px; }

/* Category tiles: an icon, a name, a count. Flex-wrap, not CSS grid, so this is
   the same in WebPositive as everywhere else. */
.cat-grid { list-style: none; padding: 0; margin: 18px 0;
  display: flex; flex-wrap: wrap; }
.cat-grid li { flex: 0 0 auto; margin: 0 12px 12px 0; }
.cat-tile {
  display: block; width: 132px; text-align: center;
  padding: 14px 10px; box-sizing: border-box;
  background: #ffffff; border: 1px solid #e4e9f1; border-radius: 12px;
  color: #1f2933; box-shadow: 0 2px 6px rgba(15, 23, 42, 0.06);
}
.cat-tile:hover { text-decoration: none; border-color: #cdd7e5;
  box-shadow: 0 6px 18px rgba(15, 23, 42, 0.13); }
.cat-tile:focus { outline: 2px solid #22d3ee; outline-offset: 2px; }
.cat-icon { width: 48px; height: 48px; display: block; margin: 0 auto 8px; }
.cat-name { display: block; font-size: 14px; font-weight: 600; color: #0f172a;
  overflow-wrap: break-word; }
.cat-tile .cat-count { display: block; margin: 4px 0 0; }

@media (max-width: 640px) {
  /* Three across on a phone: the tiles are small and square, so they do not need
     the half-width the app cards get. */
  .cat-grid { justify-content: space-between; }
  .cat-grid li { flex: 0 0 calc(33.333% - 8px); margin: 0 0 10px; }
  .cat-tile { width: 100%; padding: 10px 6px; }
  .cat-icon { width: 40px; height: 40px; }
  .cat-name { font-size: 13px; }
}

/* ---------- App detail ---------- */
/* An app page is mostly prose (summary, description, changelog). It must not
   stretch with .content, whose width is set by how many cards fit, not by how
   long a line stays readable. The pages that are prose end to end (privacy,
   about, login) set a tighter cap of their own on top of this one. */
.app-detail { background: #ffffff; border: 1px solid #e4e9f1; border-radius: 14px;
  max-width: 1000px;
  padding: 24px 26px; margin-top: 24px; box-shadow: 0 2px 8px rgba(15,23,42,0.05); }
/* flex-start, not center: the icon, the titles and the install button all start
   at the top edge. Centring them vertically let the shortest (the icon) float in
   the middle of the tallest (the titles), which opened a gap under the icon and
   pushed the button off the line the eye reads first. */
.app-detail-head { display: flex; align-items: flex-start; flex-wrap: wrap; }
/* per-child margins instead of flex gap (WebPositive); icon and cta set their
   own below, so only the titles column needs a right margin for spacing. */
.app-detail-titles { margin-right: 12px; }
.app-detail-head .app-icon { margin-right: 16px; border-radius: 16px;
  box-shadow: 0 2px 6px rgba(15,23,42,0.18); flex-shrink: 0; }
.app-detail-head h1 { margin: 0; font-size: 27px; color: #0f172a; }
.app-detail-titles { flex: 1 1 260px; }
.app-detail-titles .app-summary { color: #5b6b80; font-size: 16px; margin: 4px 0 8px; }
.app-detail-meta { margin-top: 2px; }
.app-detail-meta .badge { margin: 2px 5px 2px 0; }
/* primary action sits at the right of the header, wraps under on narrow widths */
.app-detail-cta { margin-left: auto; text-align: right; flex-shrink: 0; }
.app-detail-cta .btn { margin: 0; }
.app-detail-cta .hint { display: block; margin-top: 6px; }

/* ---------- App page: hero band + two columns ---------- */
/* The page was one 1000px column with identity, description, install and the
   technical facts stacked at the same width and the same weight -- and on an app
   with no screenshots that is a long ribbon of text with the facts a reader is
   scanning for (version, licence, architecture, who made it) buried at the bottom.
   A band that carries the identity, then content left and facts right. */
.app-page { margin-top: 24px; }

/* The band, shared. The app page wears it with an icon (.app-hero); a plain page
   wears it with a title and a sentence (.page-hero). Same surface, same ink, so
   the two pages read as one product rather than two designs. */
.page-hero, .app-hero {
  display: flex; align-items: flex-start; flex-wrap: wrap;
  padding: 22px 24px;
  border-radius: 14px;
  background: #0b1220;
  background: linear-gradient(160deg, #0b1220 0%, #1b2c4a 72%, #1e3a5f 100%);
  border: 1px solid #0a1019;
  box-shadow: 0 6px 20px rgba(15, 23, 42, 0.18);
  color: #e8eef6;
}
.page-hero { margin-top: 24px; margin-bottom: 18px; }
.page-hero-titles { flex: 1 1 320px; min-width: 0; margin-right: 12px; }
.page-hero-titles h1 { margin: 0; font-size: 28px; font-weight: 800; color: #ffffff; }
.page-hero-lead { color: #aab8cc; font-size: 16px; margin: 6px 0 0; max-width: 680px; }
.page-hero-cta { margin-left: auto; text-align: right; flex-shrink: 0; }
.page-hero-cta .btn { margin: 0; }
.page-hero-cta .hint { display: block; margin-top: 7px; color: #7b8aa3; }

@media (max-width: 640px) {
  /* The action goes under the words rather than beside them: at this width a
     right-aligned button and a paragraph fight for the same 300px. */
  .page-hero-cta { margin-left: 0; text-align: left; margin-top: 14px;
    flex: 1 1 100%; }
}

.app-hero .app-icon {
  width: 72px; height: 72px; margin-right: 18px; border-radius: 18px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45); flex-shrink: 0;
}
.app-hero-titles { flex: 1 1 280px; min-width: 0; margin-right: 12px; }
.app-hero-titles h1 { margin: 0; font-size: 30px; font-weight: 800; color: #ffffff; }
/* The summary is the one line that says what the app IS: on the dark band it gets
   the light ink it needs, not the grey it wore on white. */
.app-hero-titles .app-summary {
  color: #aab8cc; font-size: 16px; margin: 5px 0 10px; min-height: 0;
}
.app-hero-cta { margin-left: auto; text-align: right; flex-shrink: 0; }
.app-hero-cta .btn { margin: 0; }
.app-hero-cta .hint { display: block; margin-top: 7px; color: #7b8aa3; }
/* The one action the page exists for. Cyan, not the site's blue: on this band the
   blue button would sink into the gradient it sits on. */
.btn-lg {
  padding: 12px 22px; font-size: 15px;
  background: #22d3ee; color: #06222a; font-weight: 700;
}
.btn-lg:hover { background: #67e8f9; }

.app-layout { display: flex; flex-wrap: wrap; align-items: flex-start;
  margin-top: 18px; }
.app-main { flex: 1 1 64%; min-width: 0; margin-right: 2%; }
.app-rail { flex: 1 1 32%; min-width: 260px; }

/* The facts, as facts: label above value, one per line, so an eye scanning for
   "which architecture" finds it without reading a paragraph. */
.rail-title { font-size: 17px; margin-top: 0; }
.facts { margin: 10px 0 0; }
.facts dt {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em;
  color: #94a3b8; font-weight: 700; margin-top: 12px;
}
.facts dt:first-child { margin-top: 0; }
.facts dd { margin: 3px 0 0; color: #1f2933; font-size: 15px; }
.facts dd .badge { margin: 2px 4px 2px 0; }
.facts-note { color: #94a3b8; font-size: 13px; }
/* A homepage URL is one long unbroken string and would otherwise decide the width
   of the whole rail. */
.facts-url a { overflow-wrap: break-word; word-wrap: break-word; }

@media (max-width: 860px) {
  /* The rail goes under the content: two columns below this width are two columns
     of nothing. */
  .app-main { flex: 1 1 100%; margin-right: 0; }
  .app-rail { flex: 1 1 100%; min-width: 0; margin-top: 4px; }
}
@media (max-width: 640px) {
  .app-hero { flex-direction: row; padding: 18px 16px; }
  .page-hero { margin-top: 24px; margin-bottom: 18px; }
.page-hero-titles { flex: 1 1 320px; min-width: 0; margin-right: 12px; }
.page-hero-titles h1 { margin: 0; font-size: 28px; font-weight: 800; color: #ffffff; }
.page-hero-lead { color: #aab8cc; font-size: 16px; margin: 6px 0 0; max-width: 680px; }
.page-hero-cta { margin-left: auto; text-align: right; flex-shrink: 0; }
.page-hero-cta .btn { margin: 0; }
.page-hero-cta .hint { display: block; margin-top: 7px; color: #7b8aa3; }

@media (max-width: 640px) {
  /* The action goes under the words rather than beside them: at this width a
     right-aligned button and a paragraph fight for the same 300px. */
  .page-hero-cta { margin-left: 0; text-align: left; margin-top: 14px;
    flex: 1 1 100%; }
}

.app-hero .app-icon { width: 56px; height: 56px; margin-right: 14px; }
  .app-hero-titles { flex: 1 1 100%; order: 3; margin: 12px 0 0; }
  .app-hero-titles h1 { font-size: 24px; }
  /* Icon and button share the top row at opposite ends, as on the old header:
     the button is the reason the page exists and belongs where the eye lands. */
  .app-hero-cta { order: 2; }
}

/* screenshots as a horizontal strip that scrolls, not a tall stack.
   margin-right on each shot instead of flex gap (WebPositive). */
.screenshot-strip { display: flex; overflow-x: auto; padding-bottom: 6px; }
.screenshot-strip .screenshot { height: 260px; width: auto; max-width: none;
  margin: 0 12px 0 0; flex: 0 0 auto; border: 1px solid #e2e8f0; border-radius: 10px; }
.screenshot-strip .screenshot:last-child { margin-right: 0; }

/* On a phone the strip stops being a strip. Screenshots are whatever size their
   author took them at -- 311x355 next to 699x579 for one real app -- and forcing
   both to 260px tall put 554px of images side by side on a 360px screen: the
   second one lived behind a sideways scroll nobody can see is there. Stacked, at
   their own aspect ratio, each capped to the width available. They are never
   scaled UP (width: auto), because enlarging a 311px screenshot to fill the
   screen only makes it blurry. */
@media (max-width: 640px) {
  .screenshot-strip { display: block; overflow-x: visible; }
  .screenshot-strip .screenshot {
    display: block; width: auto; height: auto;
    max-width: 100%; max-height: 70vh;
    margin: 0 auto 12px;
  }
  .screenshot-strip .screenshot:last-child { margin-bottom: 0; }
}
/* The strip is for choosing a screenshot; the lightbox is for reading one. A
   screenshot of an app is mostly text, and 260px tall is not enough to see what
   the app actually looks like. */
.screenshot-zoom { cursor: zoom-in; }

/* Lightbox. position: fixed and rgba are WebPositive-safe; no CSS grid, no
   custom properties, no transitions that matter. Hidden until the JS opens it,
   so a browser with JS off simply keeps the strip it always had. */
.lightbox {
  display: none;
  position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 1000;
  background: rgba(8, 13, 24, 0.92);
  text-align: center;
}
.lightbox-img {
  max-width: 94%; max-height: 84%;
  margin-top: 4%;
  border-radius: 8px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
  cursor: default;
}
.lightbox-count {
  color: #aab8cc; font-size: 14px; margin: 10px 0 0;
}
.lightbox-close, .lightbox-prev, .lightbox-next {
  position: absolute; z-index: 1001;
  border: 1px solid #2b3a55; border-radius: 8px;
  background: rgba(14, 26, 46, 0.85); color: #e8eef6;
  cursor: pointer; line-height: 1;
}
.lightbox-close {
  top: 14px; right: 16px; font-size: 26px; padding: 4px 12px 8px;
}
.lightbox-prev, .lightbox-next {
  top: 45%; font-size: 34px; padding: 6px 16px 12px;
}
.lightbox-prev { left: 14px; }
.lightbox-next { right: 14px; }
.lightbox-close:hover, .lightbox-prev:hover, .lightbox-next:hover {
  background: #22d3ee; color: #06222a; border-color: #22d3ee;
}
.lightbox-close:focus, .lightbox-prev:focus, .lightbox-next:focus {
  outline: 2px solid #22d3ee; outline-offset: 2px;
}

/* On a phone the arrows would sit on top of the image; put them at the bottom,
   where a thumb is, and give the image the whole screen. */
@media (max-width: 640px) {
  .lightbox-img { max-width: 98%; max-height: 74%; margin-top: 12%; }
  .lightbox-prev, .lightbox-next { top: auto; bottom: 16px; font-size: 28px; }
}

.bridge-note {
  background: #ecfdf5; border: 1px solid #a7f3d0; border-left: 4px solid #10b981;
  border-radius: 8px; padding: 12px 16px; margin: 18px 0; color: #065f46;
}

.channel { background: #f8fafc; border: 1px solid #e4e9f1; border-radius: 10px;
  padding: 16px 18px; margin: 14px 0; }
/* The raw .hpkg, under the two "proper" install paths: it is the escape hatch,
   not the headline. The checksum wraps instead of stretching the card. */
.download-row { margin-top: 10px; border-top: 1px solid #e4e9f1; padding-top: 10px; }
.download-row .hint.sha code { font-size: 12px; overflow-wrap: break-word;
  word-wrap: break-word; }
.download-row .hint.sha { margin: 2px 0; }
.version-pick { margin: 10px 0 4px; }
.version-label { font-size: 14px; color: #334155; display: inline-block;
  margin-right: 8px; }
.version-select { width: auto; max-width: 220px; margin-left: 6px;
  padding: 6px 10px; }
.version-actions .btn { margin: 6px 6px 0 0; }

.channel h3 { margin: 0 0 8px; font-size: 16px; color: #0f172a; }
.channel .version { color: #64748b; font-weight: normal; font-size: 14px; }
.btn { margin: 6px 6px 6px 0; }
.hint { color: #64748b; font-size: 14px; margin: 4px 0 10px; }

.app-info p { margin: 6px 0; }
.screenshot { max-width: 100%; border: 1px solid #e2e8f0; border-radius: 10px; margin: 10px 0; }

/* ---------- Forms ---------- */
.field {
  width: 100%; max-width: 520px; padding: 9px 12px;
  border: 1px solid #cdd7e5; border-radius: 8px; font-size: 14px;
}
.field:focus { outline: none; border-color: #2563eb; }
#publish-form label, #auth-form label { font-size: 14px; color: #334155; }
#publish-form h3 { margin-top: 22px; font-size: 15px; color: #0f172a;
  border-top: 1px solid #e2e8f0; padding-top: 14px; }

/* One row per architecture: an app that ships x86_64 and x86_gcc2 is one cichéto
   with two artifacts. The inputs drop their 520px cap here, or three of them
   plus a button would not fit the row. */
.art-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.art-table th { text-align: left; padding: 4px 8px 4px 0; font-size: 13px;
  color: #64748b; font-weight: 600; }
.art-table td { padding: 3px 8px 3px 0; vertical-align: top; }
.art-table .field { max-width: none; }
.art-table td:last-child { width: 1%; white-space: nowrap; }

.pub-actions { margin-top: 18px; }
.pub-actions .btn { margin-right: 8px; }

/* Narrow screens: a four-column table of full-width inputs is unreadable, so let
   each row stack into its own block. */
@media (max-width: 640px) {
  .art-table, .art-table tbody, .art-table tr, .art-table td { display: block; width: 100%; }
  .art-table thead { display: none; }
  .art-table tr { border-bottom: 1px solid #e2e8f0; padding-bottom: 8px; margin-bottom: 8px; }
  .art-table td:last-child { width: auto; }
}

[dir="rtl"] .art-table th, [dir="rtl"] .art-table td { text-align: right;
  padding-right: 0; padding-left: 8px; }
[dir="rtl"] .pub-actions .btn { margin-right: 0; margin-left: 8px; }

/* ---------- Tabs (admin) ---------- */
/* Eight sections stacked in one column meant the thing you came for was almost
   always below the fold. Four tabs, grouped by the job. Plain buttons and a
   bottom border: no CSS grid, no custom properties, nothing WebPositive lacks. */
.tabs {
  display: flex; flex-wrap: wrap;
  border-bottom: 2px solid #e2e8f0;
  margin: 22px 0 0;
}
/* Links, not buttons: one of them loads another page (the statistics), and the
   two admin pages share this bar so the difference must not show. */
.tab {
  display: inline-block;
  background: transparent; border: 0; cursor: pointer;
  padding: 9px 14px; margin: 0 2px -2px 0;
  font-size: 15px; font-weight: 600; color: #64748b;
  border-bottom: 2px solid transparent;
  text-decoration: none; white-space: nowrap;
}
.tab:hover { color: #1f2933; text-decoration: none; }
.tab:focus { outline: 2px solid #22d3ee; outline-offset: -2px; }
.tab.is-active { color: #0f172a; border-bottom-color: #2563eb; }

/* The icon is 18px and slightly muted until its tab is the one you are on: six
   full-colour Haiku icons shouting at once would be a fruit salad, and the point
   of the colour is to tell you which one is live. */
.tab-icon {
  width: 18px; height: 18px; vertical-align: -4px; margin-right: 7px;
  opacity: 0.75;
}
.tab:hover .tab-icon, .tab.is-active .tab-icon { opacity: 1; }
.tab-label { vertical-align: baseline; }
.tab-credit { margin: 8px 0 0; font-size: 12px; }

/* No number on a tab: a count is noise on a control whose job is to take you
   somewhere. A warning is different -- a tap whose crawl failed has to be visible
   without opening the tab it lives in -- so that, and only that, gets a mark: a
   dot, with the reason in its tooltip. Nothing to warn about, nothing shown. */
.tab-dot { display: none; }
.tab-dot.is-bad {
  display: inline-block; width: 7px; height: 7px; margin-left: 7px;
  border-radius: 50%; background: #dc2626; vertical-align: middle;
}

.tab-panel { display: none; }

.admin-gate { border-left: 3px solid #22d3ee; }
.admin-result {
  background: #0f172a; color: #e2e8f0; padding: 12px;
  overflow: auto; border-radius: 6px; font-size: 13px;
}

@media (max-width: 640px) {
  /* The bar scrolls sideways rather than wrapping into two ragged lines. Seven
     entries do not fit a phone, and the icon is what makes a half-visible one
     still recognisable at the edge. */
  .tabs { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .tab { padding: 9px 10px; font-size: 14px; }
  .tab-icon { margin-right: 5px; }
}

/* ---------- Admin table ---------- */
.admin-table { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 14px;
  background: #fff; border-radius: 10px; overflow: hidden; }
.admin-table th, .admin-table td { text-align: left; padding: 9px 12px;
  border-bottom: 1px solid #e2e8f0; vertical-align: top; }
.admin-table th { color: #475569; font-weight: 600; background: #f1f5f9; }
.admin-table td .btn { padding: 4px 10px; font-size: 13px; margin: 0; }

/* ---------- Charts ---------- */
/* Inline SVG built by chart.js. One series, one y-axis, no library. The grid and
   the axis text are deliberately recessive: the shape carries the message, and
   the exact numbers live in the per-point tooltips and in the tables above. */
.chart-box { margin: 6px 0 18px; }
.chart { width: 100%; height: 160px; display: block; }
.chart-line { fill: none; stroke: #2563eb; stroke-width: 2; }
.chart-area { fill: #dbeafe; stroke: none; }
.chart-dot { fill: #2563eb; stroke: #ffffff; stroke-width: 1.5; }
.chart-hit { fill: transparent; }        /* the <title> tooltip's hit target */
.chart-grid { stroke: #e2e8f0; stroke-width: 1; }
.chart-axis { fill: #94a3b8; font-size: 11px; }
.chart-title { font-size: 15px; color: #334155; margin: 14px 0 2px; }
.chart-subtitle { font-size: 13px; color: #64748b; font-weight: 600;
  margin: 0 0 2px; }

/* Four panels over the same window, two by two. Flex, not CSS grid: this file is
   WebPositive-safe by rule. They stack on a phone, where two 160px charts side by
   side would be two smudges. */
.chart-quad { display: flex; flex-wrap: wrap; margin: 6px 0 0; }
.chart-cell { flex: 1 1 46%; min-width: 260px; margin: 0 2% 10px 0; }
@media (max-width: 640px) {
  .chart-cell { flex: 1 1 100%; min-width: 0; margin: 0 0 12px; }
}
.chart-caption { margin-top: 2px; }

@media (max-width: 640px) {
  .admin-table { font-size: 13px; }
  .admin-table th, .admin-table td { padding: 7px 8px; }
  /* An id, a repo or a referrer is one long unbroken string; without this it
     decides the column width and shoves everything else off the screen. */
  .admin-table td { overflow-wrap: break-word; word-wrap: break-word; }

  /* Label on the left, number on the right: cap the label, or a long one ("utenti
     con almeno un'app in libreria") squeezes the value it exists to explain. */
  .stats-kv th { width: 52%; }

  /* A wide table on a phone was not scrolling, it was being CUT: html/body clip
     x-overflow (the full-bleed hero needs that), so the columns past the screen
     edge did not exist at all. Rather than make it scroll sideways -- which hides
     data behind a gesture nobody knows is there -- each row becomes its own card,
     one field per line, with the column name in front of the value. The names come
     from data-label, which the JS sets when it builds the cells. */
  .table-wide, .table-wide tbody, .table-wide tr, .table-wide td {
    display: block; width: 100%;
  }
  .table-wide thead { display: none; }   /* the header is now on every cell */
  .table-wide tr {
    background: #fff; border: 1px solid #e2e8f0; border-radius: 10px;
    padding: 4px 2px; margin-bottom: 10px;
  }
  .table-wide td {
    border-bottom: 1px solid #f1f5f9; padding: 7px 10px;
    overflow-wrap: break-word; word-wrap: break-word;
  }
  .table-wide tr td:last-child { border-bottom: 0; }
  .table-wide td:before {
    content: attr(data-label) " ";
    color: #64748b; font-weight: 600; margin-right: 6px;
  }
  /* A cell with no label (an actions cell, say) should not print a stray space. */
  .table-wide td[data-label=""]:before { content: ""; }
}

/* ---------- Hero: the native Haiku client band ---------- */
/* Sits inside the dark hero, under the search. Muted while the client is still
   unreleased (.hero-client-soon), so it reads as a heads-up rather than as a
   call to action nobody can act on yet. */
.hero-client {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 8px 18px;
  max-width: 620px; margin: 20px auto 0; padding: 14px 18px;
  border: 1px solid #2b3a55; border-radius: 10px;
  background: rgba(255, 255, 255, 0.04);
  text-align: left;
}
.hero-client-text { display: flex; flex-direction: column; gap: 2px; }
.hero-client-text strong { color: #ffffff; font-size: 15px; }
.hero-client-text span { color: #aab8cc; font-size: 14px; }
.hero-client .hero-client-cta { margin: 0; flex: 0 0 auto; }
.hero-client-soon { border-style: dashed; }

@media (max-width: 640px) {
  .hero-client { flex-direction: column; align-items: stretch; text-align: center; }
  .hero-client-text { align-items: center; }
  .hero-client .hero-client-cta { width: 100%; }
}

.admin-featured { list-style: decimal inside; margin: 12px 0; padding: 0; font-size: 14px; }
.admin-featured li { display: flex; align-items: center; gap: 8px; padding: 8px 12px;
  background: #fff; border: 1px solid #e2e8f0; border-radius: 8px; margin-bottom: 6px; }
.admin-featured li > span:first-of-type { flex: 1; }
.admin-featured .btn { padding: 4px 10px; font-size: 13px; margin: 0; }
/* A pick whose cichéto a re-crawl pruned: still listed, visibly not a live app. */
.admin-featured li.stale { background: #fef2f2; border-color: #fecaca; color: #991b1b; }

/* ---------- Footer ---------- */
.site-footer { max-width: 1560px; width: 100%; margin: 28px auto 0; padding: 18px 20px;
  color: #64748b; font-size: 14px; border-top: 1px solid #d8e0ea;
  text-align: center; box-sizing: border-box; flex-shrink: 0; }
.site-footer p { max-width: 760px; margin: 0 auto; }

/* ---------- Narrow screens (phones) ----------
   The viewport meta tag is set, so honor it. WebPositive is WebKit-based and
   supports media queries; this stays within the no-grid / no-custom-properties
   constraint. Below 640px the flex headers stack and left-align instead of
   pushing the CTA off to the right. */
@media (max-width: 640px) {
  .content { padding: 0 14px 24px; }

  /* Two cards per row, not one. A phone is 360-430px wide; minus the content
     padding that leaves ~330-400px, which fits two ~165px cards comfortably --
     one full-width card per row wasted half the screen and made the catalog a
     very long scroll.
     flex-basis, not width: the base rule sets `flex: 1 1 220px`, and a flex item
     sizes from its basis, so setting width alone would change nothing. */
  .app-list { justify-content: space-between; }
  .app-card {
    flex: 0 0 calc(50% - 6px);
    width: auto; min-width: 0; max-width: none;
    margin: 0 0 12px; padding: 12px;
  }

  /* Half-width cards are ~165px wide, and two things are wider than that on
     their own: an app name with no spaces in it (beslysystemanalysistool) and a
     badge like "bacaro: haikuports". Let the text break, and cut a badge that
     still doesn't fit rather than let it push the card out of the screen. */
  .app-card .app-name, .app-card .app-summary {
    overflow-wrap: break-word; word-wrap: break-word;
  }
  .app-card .app-name { font-size: 15px; }
  .app-card .app-summary { font-size: 13px; }
  .app-card .badge {
    max-width: 100%; box-sizing: border-box;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    vertical-align: bottom;
  }

  /* app-detail header: the icon and the install button share the top row, at
     opposite ends; the name, summary and badges take the full width below.
     Stacking all three (icon, then titles, then button) left a band of dead
     space to the right of a 64px icon and pushed the button a scroll away from
     the thing it installs. The button is the reason the page exists: it belongs
     where the eye lands first. */
  .app-detail-head { flex-direction: row; flex-wrap: wrap; align-items: flex-start; }
  .app-detail-head .app-icon { margin-right: 0; order: 1; }
  .app-detail-cta {
    order: 2; margin-left: auto; text-align: right; width: auto;
  }
  .app-detail-titles { order: 3; flex: 1 1 100%; margin-right: 0; margin-top: 12px; }
  .app-detail { padding: 18px 16px; }

  /* featured shelf: stack the big card so the text isn't crowded */
  .featured-card { flex-direction: column; align-items: flex-start; }
  .featured-icon { margin-right: 0; margin-bottom: 12px; }
  .featured-cta { margin-left: 0; margin-top: 12px; }

  /* hero search fills the width */
  .search-big input { width: 100%; max-width: none; border-radius: 8px;
    display: block; margin-bottom: 8px; }
  .search-big button { width: 100%; border-radius: 8px; }
  .hero h1 { font-size: 26px; }

  /* Header on a phone, in three deliberate rows instead of whatever the wrap
     happened to produce:
       1. brand, with the language picker pushed to the far right
       2. the search box, full width
       3. the nav links
     `order` does the arranging, so the source order (which is the reading order
     for a screen reader, and the tab order) stays as it is on the desktop. */
  .site-header { padding: 10px 14px; }
  .brand { order: 1; margin-right: 0; }
  .lang-picker { order: 2; margin-left: auto; }
  .search-inline { order: 3; width: 100%; margin: 8px 0; }
  .header-nav { order: 4; width: 100%; justify-content: center; }
  .header-nav .header-link { margin: 0 8px; }

  /* The button used to drop onto a line of its own: the form was a plain block
     whose input was width:100%, so there was no room left beside it. Make the
     form the flex row and let the input take what is left over. */
  .search-inline { display: flex; align-items: center; }
  .search-inline input { flex: 1 1 auto; width: auto; min-width: 0; }
  .search-inline button { flex: 0 0 auto; }
}

/* ============================================================================
   MODERN PROFILE (browsers other than WebPositive/Haiku).
   Everything above is the lite-safe baseline that WebPositive renders fine.
   The rules below are layered ENHANCEMENT under body.ui-modern: newer browsers
   get grid, smooth transitions, richer depth and type. Guarded by @supports so
   a browser missing a feature simply keeps the baseline instead of breaking.
   The whole block is scoped to .ui-modern, so the lite profile never sees it.
   ============================================================================ */

/* Design tokens, only for the modern profile. */
.ui-modern {
  --accent: #2563eb;
  --accent-2: #22d3ee;
  --ink: #0f172a;
  --muted: #64748b;
  --card-bg: #ffffff;
  --card-border: #e6ebf3;
  --page-bg: #f6f8fc;
  --radius: 14px;
  --shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.14);
}

.ui-modern body,
body.ui-modern {
  background: var(--page-bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Header: a touch more polish and a subtle sticky elevation. */
body.ui-modern .site-header {
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 6px 20px rgba(11, 18, 32, 0.28);
}
body.ui-modern .brand,
body.ui-modern .header-link,
body.ui-modern .btn,
body.ui-modern .app-card,
body.ui-modern .badge {
  transition: color .15s ease, background-color .15s ease,
              border-color .15s ease, box-shadow .2s ease, transform .15s ease;
}

/* Card catalog: real responsive grid instead of flex-wrap widths. */
@supports (display: grid) {
  body.ui-modern .app-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 18px;
    margin: 20px 0;
  }
  body.ui-modern .app-card {
    width: auto;
    min-width: 0;
    margin: 0;              /* the grid gap handles spacing now */
  }

  /* On a phone, a 220px minimum is what forced a single column: two of them plus
     the gap want 458px, and a 390px screen has ~362px to give. 150px lets two
     columns fit on every phone (and never three: 3x150 + 2 gaps needs 486px). */
  @media (max-width: 640px) {
    body.ui-modern .app-list {
      grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
      gap: 12px;
    }
    body.ui-modern .app-card { padding: 12px; }
  }
}

body.ui-modern .app-card {
  border-radius: var(--radius);
  border-color: var(--card-border);
  box-shadow: var(--shadow-sm);
}
body.ui-modern .app-card:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(-2px);
  border-color: #cfd9ea;
}

/* Buttons: gradient accent + lift on hover. */
body.ui-modern .btn {
  border-radius: 10px;
  box-shadow: var(--shadow-sm);
}
body.ui-modern .btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(37, 99, 235, 0.28);
}

/* Badges: softer, pill-shaped. */
body.ui-modern .badge { border-radius: 999px; }

/* Respect users who ask for less motion. */
@media (prefers-reduced-motion: reduce) {
  body.ui-modern .brand,
  body.ui-modern .header-link,
  body.ui-modern .btn,
  body.ui-modern .app-card,
  body.ui-modern .badge { transition: none; }
  body.ui-modern .app-card:hover,
  body.ui-modern .btn:hover { transform: none; }
}

/* Featured carousel, modern profile: the track scrolls fluidly with snap instead
   of JS pagination. Guarded by @supports so lite/older engines keep the baseline
   (JS-paged) behaviour. */
@supports (scroll-snap-type: x mandatory) {
  body.ui-modern .featured-track {
    /* min-width:0 (from the baseline) keeps this from widening the page; here we
       swap the clipped overflow for a scrollable, snapping track. */
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    gap: 18px;
    scrollbar-width: thin;
  }
  body.ui-modern .featured-carousel .featured-card {
    /* Two per view; the gap handles spacing (drop the baseline margin) so the
       widths sum correctly and don't overflow the page. */
    flex: 0 0 calc(50% - 9px); width: calc(50% - 9px);
    margin-right: 0; scroll-snap-align: start;
  }
  /* Hide the horizontal scrollbar chrome on webkit while keeping it scrollable. */
  body.ui-modern .featured-track::-webkit-scrollbar { height: 8px; }
  body.ui-modern .featured-track::-webkit-scrollbar-thumb {
    background: #cbd5e1; border-radius: 4px;
  }
}

/* ============================================================================
   RTL (Arabic): dir="rtl" on <html> already flips text alignment and flex flow.
   These rules mirror the remaining hard-coded left/right margins so spacing
   sits on the correct side. Attribute selector -> lite-safe (WebPositive too).
   ============================================================================ */
[dir="rtl"] .brand { margin-right: 0; margin-left: 18px; }
[dir="rtl"] .search-inline { margin-right: 0; margin-left: auto; }
[dir="rtl"] .search-inline button { margin-left: 0; margin-right: 6px; }
[dir="rtl"] .header-link { margin-left: 0; margin-right: 14px; }
[dir="rtl"] .lang-picker { margin-left: 0; margin-right: 16px; }
[dir="rtl"] .featured-icon { margin-right: 0; margin-left: 22px; }
[dir="rtl"] .featured-cta { margin-left: 0; margin-right: 22px; }
[dir="rtl"] .featured-carousel .featured-card { margin-right: 0; margin-left: 2%; }
[dir="rtl"] .featured-carousel .featured-card:last-child { margin-left: 0; }
[dir="rtl"] .also-in .source-list .badge { margin-left: 0; margin-right: 8px; }
[dir="rtl"] .pager > * { margin-right: 0; margin-left: 12px; }
[dir="rtl"] .pager > *:last-child { margin-left: 0; }
/* Rounded search input: swap the flat corners for RTL. */
[dir="rtl"] .search-big input { border-radius: 0 8px 8px 0; }
[dir="rtl"] .search-big button { border-radius: 8px 0 0 8px; }
