/* =============================================================================
   Public design system for the Laravel-rendered pages (docs/09 P1-1 redesign).

   Shared, app-branded stylesheet for what Laravel still renders on the main
   domain: the /blog pages and /content-removal, on `public/layout.blade.php`
   with the header/footer partials. Every public CONTENT page (`/discover/…`,
   `/import`) is the web app's since decision log 2026-09-10 and styled by
   its Tailwind build; the reader, level-tab, media and funnel rules that
   dressed the old Blade article/video/music pages were deleted with them
   (Phase 4). Every value here is lifted verbatim from the app's "Linguistic
   Workspace" design tokens (packages/design-tokens/src/index.ts, semantic
   layer) — the slate neutral ramp, teal primary accent, Inter body / Geist
   label font stacks, 4px radius scale, and 8px/4px spacing rhythm. Depth
   comes from tonal layering + 1px outlines, never heavy shadows (DESIGN.md §8).

   This is plain CSS with the token VALUES inlined as `--la-*` custom
   properties: the app's React/Tailwind build is NOT imported into Blade (that
   would drag in the whole SPA). Served static from
   apps/backend/public/css/public.css. Everything reads and renders with NO JS.

   These values MIRROR the DEFAULT palette in packages/design-tokens by hand, and
   they drifted once already. `publicCss.test.ts` in that package now reads this
   file and fails if any value here disagrees, so the mirror stays honest.

   Having no JS, this page cannot follow a viewer's chosen theme — it always
   renders the default palette. That is a deliberate limit, not an oversight.
============================================================================= */

:root {
  /* --- Surfaces (tonal layering; L0 -> L1 -> L2) --- */
  --la-background: #eef2f7;
  --la-surface: #ffffff;
  --la-surface-raised: #ffffff;
  --la-surface-muted: #dee5ee;

  /* --- Text --- */
  --la-text: #0b1c30;
  --la-text-muted: #475569;
  --la-text-subtle: #4f5b6b;

  /* --- Structure (1px borders; shift to accent on focus) --- */
  --la-border: #c2cddb;
  --la-border-strong: #a3b2c4;

  /* --- Functional accents --- */
  --la-accent: #00685f; /* teal600 — primary CTA */
  --la-accent-strong: #00685f;
  --la-accent-muted: #99f6e4; /* teal tonal wash */
  --la-on-accent: #ffffff;
  --la-secondary: #4f46e5; /* indigo */
  --la-secondary-muted: #dfe2fd;
  --la-tertiary: #d97706; /* amber */
  --la-tertiary-muted: #fde9b8;
  --la-neutral: #4f5b6b;
  --la-focus: #0d9488; /* teal500 — focus ring */
  --la-selection: #cfe3f7;
  --la-danger: #b91c1c;

  /* --- Shape (4px default; 2/6/8 around it; no pills for surfaces) --- */
  --la-radius-small: 2px;
  --la-radius: 4px;
  --la-radius-medium: 6px;
  --la-radius-large: 8px;

  /* --- Spacing rhythm (8/4 base) --- */
  --la-space-xxs: 2px;
  --la-space-xs: 4px;
  --la-space-sm: 8px;
  --la-space-md: 12px;
  --la-space-lg: 16px;
  --la-space-xl: 24px;
  --la-space-xxl: 32px;
  --la-space-xxxl: 48px;

  /* --- Typography families (match the app's self-hosted fallback chains;
         Inter/Geist load if present, else graceful system fallback) --- */
  --la-font-body:
    "Inter Variable", Inter, ui-sans-serif, system-ui, -apple-system,
    BlinkMacSystemFont, "Segoe UI", sans-serif;
  --la-font-label:
    "Geist Variable", Geist, "Inter Variable", Inter, ui-sans-serif, system-ui,
    -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  /* Reading surface: a warm serif for long-form article body (Easy-French-News
     reader model — comfortable measure + literary feel), distinct from the UI
     sans so body copy reads as "content", chrome reads as "app". */
  --la-font-reading: Georgia, "Iowan Old Style", "Times New Roman", serif;
}

/* --------------------------------------------------------------------------
   Reset / base
-------------------------------------------------------------------------- */
* {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  margin: 0;
  background: var(--la-background);
  color: var(--la-text);
  font-family: var(--la-font-body);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* No horizontal overflow — the product-smoke suite guards this on /read. */
  overflow-x: hidden;
}
a {
  color: var(--la-accent);
  text-decoration: none;
  text-underline-offset: 2px;
}
a:hover {
  text-decoration: underline;
}
/* Keyboard-first: consistent 2px offset focus ring in the token color. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--la-focus);
  outline-offset: 2px;
  border-radius: var(--la-radius-small);
}
img {
  max-width: 100%;
  height: auto;
  display: block;
}
::selection {
  background: var(--la-selection);
}
/* --------------------------------------------------------------------------
   Layout shell
-------------------------------------------------------------------------- */
/* Restored 2026-10-06: Phase 4 (#420) deleted these as dead, but every page
   still rendered here (/blog, /method) wraps its <main> — and the header and
   footer rows — in `.shell`, so the blog lost its gutters and its measure.
   The header and footer rows set their own wider measure below. */
.shell {
  max-width: 44rem;
  margin: 0 auto;
  padding: 0 var(--la-space-lg);
}
.shell--wide {
  max-width: 80rem; /* the app shell's max-w-7xl */
}
main.shell,
main .shell {
  padding-bottom: var(--la-space-xxxl);
}

/* The island mount scripts (partials/hub_island + reader_island) set [hidden]
   on the SSR fallback wrappers after a proven mount. Explicit here, so no
   later `display` rule on those wrappers can ever out-rank the UA default. */
[data-hub-ssr-fallback][hidden],
[data-reader-ssr-fallback][hidden] {
  display: none;
}

/* --------------------------------------------------------------------------
   Site header — mirrors the app's AppHeader (apps/web/src/app/AppHeader.tsx)
   value for value so the public pages and the app read as ONE product:
   sticky 56px bar, 80rem inner (Tailwind max-w-7xl), 36px nav links / pill /
   button, 4px radius (rounded-la). Keep the two in step by hand.
-------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  border-bottom: 1px solid var(--la-border);
  background: var(--la-surface);
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  height: 3.5rem;
  width: 100%;
  max-width: 80rem;
  margin: 0 auto;
  padding: 0 1rem;
}
.site-header__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--la-space-sm);
  font-weight: 600;
  font-size: 0.9375rem;
  letter-spacing: -0.01em;
  color: var(--la-text);
}
.site-header__brand:hover {
  text-decoration: none;
}
.site-header__mark {
  display: block;
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 6px;
  object-fit: cover;
  background: var(--la-accent);
}
.site-header__nav {
  display: flex;
  align-items: center;
  gap: var(--la-space-xs);
  font-family: var(--la-font-label);
}
.site-header__nav a {
  display: inline-flex;
  align-items: center;
  height: 2.25rem;
  padding: 0 0.75rem;
  border-radius: var(--la-radius);
  font-size: 0.875rem;
  color: var(--la-text-muted);
}
.site-header__nav a:hover {
  color: var(--la-text);
  text-decoration: none;
}
.site-header__nav a[aria-current="page"] {
  color: var(--la-text);
  font-weight: 500;
}
.site-header__spacer {
  flex: 1;
}
/* Reading-language pill (the app's language switcher trigger). */
.site-header__lang {
  display: none;
  align-items: center;
  height: 2.25rem;
  padding: 0 0.75rem;
  border-radius: var(--la-radius);
  background: var(--la-accent-muted);
  color: var(--la-accent-strong);
  font-family: var(--la-font-label);
  font-size: 0.875rem;
  font-weight: 600;
  white-space: nowrap;
}
/* Primary button (the app's account CTA). */
.site-header__cta {
  display: inline-flex;
  align-items: center;
  height: 2.25rem;
  padding: 0 0.875rem;
  border-radius: var(--la-radius);
  background: var(--la-accent);
  color: var(--la-on-accent);
  font-family: var(--la-font-label);
  font-size: 0.875rem;
  font-weight: 500;
  white-space: nowrap;
}
.site-header__cta:hover {
  text-decoration: none;
  opacity: 0.9;
}
@media (min-width: 34rem) {
  .site-header__lang {
    display: inline-flex;
  }
}
@media (min-width: 40rem) {
  .site-header__inner {
    padding: 0 1.5rem; /* sm:px-6 */
  }
}
/* A phone: the wordmark and the account button on the first row, the section
   links on a second — three links and the button never fit one 375px row. */
@media (max-width: 39.99rem) {
  .site-header__inner {
    flex-wrap: wrap;
    height: auto;
    padding-bottom: var(--la-space-xs);
    padding-top: var(--la-space-sm);
    row-gap: var(--la-space-xs);
  }
  .site-header__nav {
    margin-left: -0.75rem;
    order: 3;
    width: calc(100% + 0.75rem);
  }
  .site-header__nav a {
    height: 2rem;
  }
}

/* --------------------------------------------------------------------------
   Breadcrumb + generic page heading blocks
-------------------------------------------------------------------------- */
.crumbs {
  color: var(--la-text-subtle);
  font-family: var(--la-font-label);
  font-size: 0.875rem;
  margin: var(--la-space-xl) 0 var(--la-space-lg);
}
.crumbs a {
  color: var(--la-text-muted);
}
.page-head {
  margin: var(--la-space-xl) 0 var(--la-space-xl);
}
h1 {
  font-family: var(--la-font-body);
  font-size: 2rem;
  line-height: 1.2;
  letter-spacing: -0.02em;
  font-weight: 600;
  margin: 0 0 var(--la-space-md);
}
.intro,
.lede {
  color: var(--la-text-muted);
  font-size: 1.0625rem;
  line-height: 1.55;
  margin: 0 0 var(--la-space-lg);
}
/* --------------------------------------------------------------------------
   Card grid (news / stories / language directory)
-------------------------------------------------------------------------- */
.card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--la-space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 34rem) {
  .card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 60rem) {
  .card-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
.card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--la-border);
  border-radius: var(--la-radius-large);
  background: var(--la-surface);
  overflow: hidden;
  transition:
    border-color 120ms ease,
    transform 120ms ease;
}
.card:hover {
  border-color: var(--la-border-strong);
}
.card__body {
  display: flex;
  flex-direction: column;
  gap: var(--la-space-sm);
  padding: var(--la-space-lg);
  flex: 1;
}
.card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--la-space-sm);
  color: var(--la-text-subtle);
  font-family: var(--la-font-label);
  font-size: 0.75rem;
}
.card__topic {
  display: inline-block;
  border-radius: 999px;
  background: var(--la-accent-muted);
  color: var(--la-accent);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  padding: 0.15rem 0.55rem;
}
.card__title {
  font-family: var(--la-font-body);
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  margin: 0;
}
.card__title a {
  color: var(--la-text);
}
.card__excerpt {
  color: var(--la-text-muted);
  font-size: 0.9375rem;
  line-height: 1.5;
  margin: 0;
}
.card__more {
  margin-top: auto;
  color: var(--la-accent);
  font-family: var(--la-font-label);
  font-size: 0.875rem;
  font-weight: 600;
}
/* Language directory cards are lighter (no media). */
.card--language .card__body {
  gap: var(--la-space-xs);
}

.empty-note {
  border: 1px dashed var(--la-border);
  border-radius: var(--la-radius-large);
  color: var(--la-text-muted);
  padding: var(--la-space-xl);
  text-align: center;
}
/* --------------------------------------------------------------------------
   Article page
-------------------------------------------------------------------------- */

.article-head {
  margin: 0 0 var(--la-space-lg);
}
.page-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--la-space-sm);
  color: var(--la-text-subtle);
  font-family: var(--la-font-label);
  font-size: 0.8125rem;
  margin: var(--la-space-md) 0 0;
}

/* Reading typography — comfortable measure, serif body. */
.article-body {
  font-family: var(--la-font-reading);
}
.article-body p {
  font-size: 1.1875rem;
  line-height: 1.75;
  margin: 0 0 var(--la-space-lg);
}
.article-body h2 {
  font-family: var(--la-font-body);
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.3;
  margin: var(--la-space-xxl) 0 var(--la-space-md);
}
/* Lists in prose (the /content-removal policy page) read at the paragraph
   size; article bodies are paragraph-only today, so nothing else shifts. */
.article-body ul,
.article-body ol {
  font-size: 1.1875rem;
  line-height: 1.75;
  margin: 0 0 var(--la-space-lg);
  padding-left: 1.5rem;
}
.article-body li + li {
  margin-top: var(--la-space-sm);
}
/* Non-active level bodies stay in the initial HTML (SEO + no-JS reach) but
   are visually hidden once the tabs script marks them [hidden]. Without JS
   every level renders stacked and readable — the [data-level-panel] sections
   simply flow one after another under their level heading. */
[data-level-panel][hidden] {
  display: none;
}

/* --------------------------------------------------------------------------
   Footer
-------------------------------------------------------------------------- */
.site-footer {
  border-top: 1px solid var(--la-border);
  background: var(--la-surface);
  color: var(--la-text-subtle);
  font-size: 0.875rem;
}
.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--la-space-md);
  /* The header's measure and gutter (.site-header__inner): no `.shell` rule gives one. */
  max-width: 80rem;
  margin: 0 auto;
  padding: var(--la-space-xl) 1rem;
}
.site-footer__inner p {
  margin: 0;
}
.site-footer a {
  color: var(--la-text-muted);
}
/* Footer utility links (Content removal, …), pushed to the far edge. */
.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--la-space-md);
  margin-left: auto;
}
/* ---------------------------------------------------------------------------
   Blog body prose (/blog)
   ---------------------------------------------------------------------------
   The blog reuses .article-body for its paragraph rhythm, and adds only what a
   marketing page needs that a learner text does not: comparison tables, deeper
   headings, quotes and code.

   The comparison table is the highest-value element on a VS page — it is what
   both a skimming reader and an answer engine extract — so it gets real borders
   and padding rather than inheriting the bare browser default. Set in the same
   --la-* tokens as the rest of this file, mirrored by hand from
   packages/design-tokens; no new stylesheet, because a new file would need
   three more synchronized edits (Caddy proxy matcher, Caddy cache matcher, the
   vite dev-proxy regex).
   --------------------------------------------------------------------------- */
.blog-body h3 {
  font-family: var(--la-font-body);
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.35;
  margin: var(--la-space-xl) 0 var(--la-space-sm);
}
.blog-body h4 {
  font-family: var(--la-font-body);
  font-size: 1rem;
  font-weight: 600;
  margin: var(--la-space-lg) 0 var(--la-space-xs);
}
/* Wide tables scroll inside their own box: the page body must never scroll
   sideways on a phone. */
.blog-body table {
  border-collapse: collapse;
  display: block;
  font-family: var(--la-font-body);
  font-size: 1rem;
  margin: 0 0 var(--la-space-xl);
  max-width: 100%;
  overflow-x: auto;
  width: 100%;
}
.blog-body th,
.blog-body td {
  border: 1px solid var(--la-border);
  padding: var(--la-space-md) var(--la-space-lg);
  text-align: left;
  vertical-align: top;
}
.blog-body thead th {
  background: var(--la-surface-muted);
  border-bottom-color: var(--la-border-strong);
  font-weight: 600;
}
.blog-body tbody tr:nth-child(even) td {
  background: var(--la-surface-muted);
}
.blog-body blockquote {
  border-left: 3px solid var(--la-border-strong);
  color: var(--la-text-muted);
  margin: 0 0 var(--la-space-xl);
  padding: var(--la-space-xs) 0 var(--la-space-xs) var(--la-space-lg);
}
.blog-body code {
  background: var(--la-surface-muted);
  border-radius: var(--la-radius-small);
  font-size: 0.9375rem;
  padding: 0.1em 0.35em;
}
.blog-body pre {
  background: var(--la-surface-muted);
  border-radius: var(--la-radius);
  margin: 0 0 var(--la-space-xl);
  overflow-x: auto;
  padding: var(--la-space-lg);
}
.blog-body pre code {
  background: none;
  padding: 0;
}
.blog-body hr {
  border: 0;
  border-top: 1px solid var(--la-border);
  margin: var(--la-space-xxl) 0;
}

/* The visible FAQ. Mirrors the FAQPage JSON-LD one-for-one — structured data
   must match what a reader actually sees. */
.blog-faq {
  margin-top: var(--la-space-xxxl);
}
.blog-faq h2 {
  font-family: var(--la-font-body);
  font-size: 1.375rem;
  font-weight: 600;
  margin: 0 0 var(--la-space-lg);
}
.blog-faq dt {
  font-family: var(--la-font-body);
  font-weight: 600;
  margin-top: var(--la-space-lg);
}
.blog-faq dd {
  color: var(--la-text-muted);
  margin: var(--la-space-xs) 0 0;
}

/* The live Content list on a collection page. */
.blog-collection {
  margin-top: var(--la-space-xxl);
}

/* "Facts checked <month>" on a comparison page: a dated claim, deliberately
   visible rather than buried in markup. */
.page-meta__facts {
  color: var(--la-text-subtle);
}

/* ---------------------------------------------------------------------------
   The method pages (/method, /method/spaced-repetition) — decision log
   2026-10-06 "Method pages"
   ---------------------------------------------------------------------------
   Long-form pages on the blog's prose rhythm (.article-body + .blog-body: the
   serif measure, tables, quotes, h3). Added here only what a manifesto needs:
   its own measure and gutters, the hero, the table of contents, the bold
   lead-ins that open each part of a principle, the reference list and the
   read-next cards. The ids come from the Markdown's own headings
   (MethodDocument), so `#what-we-believe` and `#sources` are stable.
   --------------------------------------------------------------------------- */
/* The measure and the gutters are main.shell's. */
.method {
  margin: 0 auto;
}
.method-hero {
  margin: 0 0 var(--la-space-xl);
}
.method-eyebrow {
  color: var(--la-accent);
  font-family: var(--la-font-label);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  margin: 0 0 var(--la-space-sm);
  text-transform: uppercase;
}
.method h1 {
  font-size: 2.25rem;
  line-height: 1.15;
}
.method-lede {
  color: var(--la-text-muted);
  font-size: 1.1875rem;
  line-height: 1.6;
  margin: 0 0 var(--la-space-md);
}
.method-toc {
  background: var(--la-surface);
  border: 1px solid var(--la-border);
  border-radius: var(--la-radius-large);
  font-family: var(--la-font-label);
  font-size: 0.9375rem;
  margin: 0 0 var(--la-space-xxl);
  padding: var(--la-space-lg) var(--la-space-xl);
}
.method-toc__title {
  font-weight: 600;
  margin: 0 0 var(--la-space-sm);
}
.method-toc ul {
  column-gap: var(--la-space-xl);
  columns: 2 15rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.method-toc li {
  break-inside: avoid;
  margin: 0 0 var(--la-space-xs);
}
/* Under the sticky header when a contents link jumps to a heading (two rows on a phone). */
.method-body h2,
.method-body h3 {
  scroll-margin-top: 6.5rem;
}
@media (min-width: 40rem) {
  .method-body h2,
  .method-body h3 {
    scroll-margin-top: 4.5rem;
  }
}
.method-body h2 {
  border-top: 1px solid var(--la-border);
  font-size: 1.5rem;
  padding-top: var(--la-space-xl);
}
/* "What the research says." / "What BetterLang does." / "Where the evidence stops." */
.method-body p > strong:first-child {
  color: var(--la-text);
  font-family: var(--la-font-body);
  font-size: 1rem;
  letter-spacing: -0.005em;
}
/* The beliefs: the manifesto itself, set larger than the prose around it. */
.method-body #what-we-believe + ol {
  font-family: var(--la-font-body);
  font-size: 1.25rem;
  line-height: 1.5;
}
.method-body #what-we-believe + ol li + li {
  margin-top: var(--la-space-md);
}
/* The reference list: smaller, and a long URL wraps instead of widening the page. */
.method-body #sources + ol {
  font-family: var(--la-font-body);
  font-size: 0.9375rem;
  line-height: 1.55;
  overflow-wrap: anywhere;
}
.method-next {
  display: grid;
  gap: var(--la-space-lg);
  margin: var(--la-space-xxxl) 0 0;
}
.method-next__card {
  background: var(--la-surface);
  border: 1px solid var(--la-border);
  border-radius: var(--la-radius-large);
  color: var(--la-text);
  display: block;
  padding: var(--la-space-lg) var(--la-space-xl);
}
.method-next__card:hover {
  border-color: var(--la-accent);
  text-decoration: none;
}
.method-next__label {
  color: var(--la-accent);
  display: block;
  font-family: var(--la-font-label);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.method-next__title {
  display: block;
  font-size: 1.125rem;
  font-weight: 600;
  margin: var(--la-space-xs) 0;
}
.method-next__text {
  color: var(--la-text-muted);
  display: block;
  font-size: 0.9375rem;
}
.method-cta {
  align-items: center;
  background: var(--la-surface-muted);
  border-radius: var(--la-radius-large);
  display: flex;
  flex-wrap: wrap;
  gap: var(--la-space-md);
  justify-content: space-between;
  padding: var(--la-space-lg) var(--la-space-xl);
}
.method-cta p {
  font-weight: 600;
  margin: 0;
}
.method-cta__button {
  align-items: center;
  background: var(--la-accent);
  border-radius: var(--la-radius);
  color: var(--la-on-accent);
  display: inline-flex;
  font-family: var(--la-font-label);
  font-weight: 500;
  height: 2.5rem;
  padding: 0 1rem;
}
.method-cta__button:hover {
  opacity: 0.9;
  text-decoration: none;
}
@media (min-width: 48rem) {
  .method h1 {
    font-size: 2.75rem;
  }
}
