/* ════════════════════════════════════════════════════════════════
   STARFOUNDRY — Localisation layer styling (sf-i18n)

   Scope of this file:
     · the injected #sf-lang language selector
     · dormant per-language typography hooks (:root[lang="…"])

   It defines NO rule that targets existing page markup, with one
   deliberate exception documented at "Localisation-specific
   adjustments" near the bottom. Nothing here changes the site's
   appearance in English.

   ── Positioning contract ────────────────────────────────────────
   The selector is a fixed-position sibling of the existing
   #sf-sound-btn control, never a child of <nav> (inserting a fourth
   flex child into <nav> would redistribute the existing bar).

   Because every page hardcodes its own #sf-sound-btn offset, the
   selector's offset is a variable a page can override in one line:

       #sf-lang{ --sf-lang-right: 12.2rem; --sf-lang-right-m: 1.5rem; }

   The defaults below are tuned for the standard Starfoundry app-page
   nav (brand · links · "← Galaxy" · ♪), where:
     · above 768px  "← Galaxy" occupies the far right, so the selector
       sits to the LEFT of the ambience button;
     · at/below 768px  .nav-back is display:none, freeing the far
       right, so the selector moves THERE — clear of both the brand
       and the ambience button on a 375px screen.
   ════════════════════════════════════════════════════════════════ */

#sf-lang {
  /* Tint — override per page to match that world's palette.
     Format is a bare "r,g,b" triple so alpha can vary below. */
  --sf-lang-accent: 255, 255, 255;
  --sf-lang-fg: 255, 255, 255;

  /* Offsets — see positioning contract above. */
  --sf-lang-top: 1.05rem;
  --sf-lang-right: 12.2rem;
  --sf-lang-top-t: 3.7rem;
  --sf-lang-right-t: 3rem;
  --sf-lang-top-m: 0.8rem;
  --sf-lang-right-m: 1.5rem;

  position: fixed;
  top: var(--sf-lang-top);
  right: var(--sf-lang-right);
  left: auto;
  z-index: 99999;
  font-family: 'DM Sans', sans-serif;
  line-height: 1;
  -webkit-tap-highlight-color: transparent;
}

/* The butterfly-cursor system sets `cursor:none !important` on html,
   body, a and button. Inheriting keeps this control consistent on
   those pages, while pages without that system (privacy, terms) keep
   a normal pointer. Never hardcode `cursor:none` here. */
#sf-lang,
#sf-lang * {
  cursor: inherit;
}

/* ── Closed control ─────────────────────────────────────────────
   Mirrors #sf-sound-btn: same border weight, same glass, same glow,
   same transition set — so it reads as a sibling, not an add-on. */

#sf-lang-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.28em;
  height: 34px;
  padding: 0 0.62rem;
  border: 1.5px solid rgba(var(--sf-lang-accent), 0.55);
  border-radius: 17px;
  background: rgba(0, 0, 0, 0.18);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: rgba(var(--sf-lang-fg), 0.9);
  box-shadow: 0 0 10px rgba(var(--sf-lang-accent), 0.1),
              0 0 20px rgba(var(--sf-lang-accent), 0.05);
  transition: border-color 0.3s, color 0.3s, box-shadow 0.3s,
              background 0.3s, opacity 0.3s;
  outline: none;
  font-family: inherit;
  user-select: none;
  opacity: 0.82;
}

#sf-lang-btn:hover,
#sf-lang-btn:focus-visible,
#sf-lang.sf-lang-open #sf-lang-btn {
  border-color: rgba(var(--sf-lang-accent), 0.88);
  color: rgba(var(--sf-lang-fg), 1);
  box-shadow: 0 0 14px rgba(var(--sf-lang-accent), 0.22);
  opacity: 1;
}

#sf-lang-btn:focus-visible {
  outline: 1px solid rgba(var(--sf-lang-accent), 0.75);
  outline-offset: 2px;
}

/* Enlarge the touch target to 44px without changing the visual size. */
#sf-lang-btn::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: max(100%, 44px);
  height: 44px;
}

.sf-lang-code {
  font-size: 0.5rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 400;
}

.sf-lang-caret {
  font-size: 0.5rem;
  line-height: 1;
  opacity: 0.7;
  transition: transform 0.3s, opacity 0.3s;
}

#sf-lang.sf-lang-open .sf-lang-caret {
  transform: rotate(180deg);
  opacity: 1;
}

/* ── Open menu ─────────────────────────────────────────────────── */

#sf-lang-menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  margin: 0;
  padding: 0.3rem 0;
  list-style: none;
  min-width: 8.4rem;
  border: 1.5px solid rgba(var(--sf-lang-accent), 0.4);
  border-radius: 10px;
  background: rgba(6, 4, 18, 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45),
              0 0 18px rgba(var(--sf-lang-accent), 0.08);
  z-index: 100000;
  max-height: min(70vh, 24rem);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

#sf-lang-menu[hidden] {
  display: none !important;
}

#sf-lang-menu li {
  display: flex;
  align-items: center;
  min-height: 36px;
  padding: 0 1.5rem 0 0.85rem;
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  color: rgba(240, 234, 224, 0.62);
  white-space: nowrap;
  transition: color 0.25s, background 0.25s;
  outline: none;
  position: relative;
}

#sf-lang-menu li:hover,
#sf-lang-menu li:focus {
  color: rgba(var(--sf-lang-fg), 1);
  background: rgba(var(--sf-lang-accent), 0.1);
}

#sf-lang-menu li:focus-visible {
  box-shadow: inset 0 0 0 1px rgba(var(--sf-lang-accent), 0.6);
}

#sf-lang-menu li[aria-selected="true"] {
  color: rgba(var(--sf-lang-fg), 1);
}

/* Checkmark on the active language — positioned in the reserved
   right padding so selecting never reflows the list. */
#sf-lang-menu li[aria-selected="true"]::after {
  content: '\2713';
  position: absolute;
  right: 0.6rem;
  font-size: 0.55rem;
  opacity: 0.8;
}

/* Offered by the design but not yet translated: visible, dimmed,
   and inert. Better an honest gap than a half-translated page. */
#sf-lang-menu li[aria-disabled="true"] {
  color: rgba(240, 234, 224, 0.24);
  pointer-events: none;
}

/* ── Narrow desktop / landscape tablet (769–900px) ──────────────
   The tightest band on the site. The nav still shows links, "← Galaxy"
   AND the ♪ button, leaving under 40px between the last nav link and
   the ambience control — measured 16px of overlap at 769px. Rather
   than reflow the existing nav, the selector drops one row beneath it,
   still right-aligned to the nav's own 3rem gutter. */

@media (min-width: 769px) and (max-width: 900px) {
  #sf-lang {
    top: var(--sf-lang-top-t);
    right: var(--sf-lang-right-t);
  }
}

/* ── Mobile / tablet portrait ───────────────────────────────────
   .nav-back is display:none below 769px, so the far right is free —
   the selector moves there, well clear of the brand and the ♪ button. */

@media (max-width: 768px) {
  #sf-lang {
    top: var(--sf-lang-top-m);
    right: var(--sf-lang-right-m);
  }

  #sf-lang-btn {
    height: 30px;
    padding: 0 0.55rem;
    border-radius: 15px;
  }

  .sf-lang-code { font-size: 0.46rem; }
  .sf-lang-caret { font-size: 0.46rem; }

  /* Comfortable thumb targets in the open list. */
  #sf-lang-menu li {
    min-height: 44px;
    font-size: 0.7rem;
  }

  #sf-lang-menu { min-width: 9.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  #sf-lang-btn,
  .sf-lang-caret,
  #sf-lang-menu li {
    transition: none;
  }
}

/* ════════════════════════════════════════════════════════════════
   PER-LANGUAGE TYPOGRAPHY HOOKS

   Dormant until a pack for that language ships. Every rule is scoped
   to :root[lang="…"], so English and German are untouched.
   ════════════════════════════════════════════════════════════════ */

/* ── CJK / Hangul font coverage (ja / ko) ───────────────────────
   The site's six webfonts (Cormorant Garamond, DM Sans, Playfair
   Display, Cinzel, EB Garamond, Baloo 2) carry NO CJK or Hangul
   coverage. Roughly two dozen elements on a page declare their own
   font-family rather than inheriting from <body> — .feat-name,
   .section-label, .nav-back, the buttons, the footer links, and
   three elements with inline style="font-family:…" that a stylesheet
   cannot override without !important. Overriding each of them by
   class would be fragile and would need repeating on all twelve
   remaining pages.

   Instead each existing family NAME is extended with an extra
   @font-face restricted by unicode-range to CJK/Hangul codepoints
   and sourced from local() system fonts. Any element that already
   says font-family:'DM Sans' therefore picks up a proper Japanese or
   Korean face for Japanese or Korean characters only — with no change
   to a single existing declaration, inline styles included, and no
   webfont download.

   These rules are intentionally NOT scoped to :root[lang]: a CJK
   glyph should render in a CJK face wherever it appears. For the six
   Latin languages no codepoint in these ranges is ever used, so the
   faces never load and nothing changes.

   Ranges: CJK punctuation, Hiragana, Katakana, CJK ideographs and
   fullwidth forms go to the Japanese faces; Hangul jamo and syllables
   go to the Korean faces. Shared punctuation is assigned to the
   Japanese face — the system fonts render it identically.         */

/* Sans families → system Gothic */
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 100 900;
  src: local('Hiragino Kaku Gothic ProN'), local('Hiragino Sans'),
       local('Yu Gothic Medium'), local('Yu Gothic'), local('Meiryo'),
       local('Noto Sans JP'), local('Noto Sans CJK JP');
  unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF,
                 U+4E00-9FFF, U+FF00-FFEF;
}

@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 100 900;
  src: local('Apple SD Gothic Neo'), local('Noto Sans KR'),
       local('Noto Sans CJK KR'), local('Malgun Gothic');
  unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F,
                 U+AC00-D7AF, U+D7B0-D7FF;
}

/* Serif / display families → system Mincho and Batang */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 100 900;
  src: local('Hiragino Mincho ProN'), local('Yu Mincho'),
       local('Noto Serif JP'), local('Noto Serif CJK JP'), local('MS Mincho');
  unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF,
                 U+4E00-9FFF, U+FF00-FFEF;
}

@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 100 900;
  src: local('Apple SD Gothic Neo'), local('Noto Serif KR'),
       local('Noto Serif CJK KR'), local('Batang');
  unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F,
                 U+AC00-D7AF, U+D7B0-D7FF;
}

@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 100 900;
  src: local('Hiragino Mincho ProN'), local('Yu Mincho'),
       local('Noto Serif JP'), local('Noto Serif CJK JP'), local('MS Mincho');
  unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF,
                 U+4E00-9FFF, U+FF00-FFEF;
}

@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 100 900;
  src: local('Apple SD Gothic Neo'), local('Noto Serif KR'),
       local('Noto Serif CJK KR'), local('Batang');
  unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F,
                 U+AC00-D7AF, U+D7B0-D7FF;
}

/* CJK text needs a little more leading than the site's tight Latin
   display line-heights allow, or ascenders and descenders collide. */
:root[lang="ja"] .section-body, :root[lang="ko"] .section-body,
:root[lang="ja"] .hero-body,    :root[lang="ko"] .hero-body,
:root[lang="ja"] .feat-desc,    :root[lang="ko"] .feat-desc {
  line-height: 1.95;
}

:root[lang="ja"] .hero-title, :root[lang="ko"] .hero-title,
:root[lang="ja"] .section-title, :root[lang="ko"] .section-title {
  line-height: 1.32;
}

/* Small uppercase Latin micro-labels → normal case, tighter tracking,
   slightly larger, because CJK glyphs need more vertical room than a
   7px uppercase Latin label. */
:root[lang="ja"] .section-label, :root[lang="ko"] .section-label,
:root[lang="ja"] .hero-eyebrow,  :root[lang="ko"] .hero-eyebrow,
:root[lang="ja"] .nav-links a,   :root[lang="ko"] .nav-links a,
:root[lang="ja"] .nav-back,      :root[lang="ko"] .nav-back,
:root[lang="ja"] .footer-legal-link, :root[lang="ko"] .footer-legal-link {
  text-transform: none;
  letter-spacing: 0.06em;
  font-size: 0.62rem;
}

:root[lang="ja"] .sf-lang-code, :root[lang="ko"] .sf-lang-code {
  letter-spacing: 0.1em;
}

/* Homepage equivalents of the same Latin-only devices. The homepage
   uses its own class names (.h-eyebrow rather than .hero-eyebrow, plus
   the scroll hint, stat labels, panel meta and panel CTAs), so they fall
   outside the app-page list above and kept .18em–.42em tracking with
   uppercase on Japanese and Korean. Only tracking and casing are reset
   here — font sizes are deliberately left at their authored values so
   the homepage layout is unchanged. */
:root[lang="ja"] .h-eyebrow,   :root[lang="ko"] .h-eyebrow,
:root[lang="ja"] .scr-hint,    :root[lang="ko"] .scr-hint,
:root[lang="ja"] .s2-eyebrow,  :root[lang="ko"] .s2-eyebrow,
:root[lang="ja"] .s2-stat-l,   :root[lang="ko"] .s2-stat-l,
:root[lang="ja"] .ap-no,       :root[lang="ko"] .ap-no,
:root[lang="ja"] .ap-bd,       :root[lang="ko"] .ap-bd,
:root[lang="ja"] .ap-link,     :root[lang="ko"] .ap-link {
  text-transform: none;
  letter-spacing: 0.06em;
}

/* CJK has no true italic, so the browser synthesises a slant. The
   homepage sets font-style:italic on the hero sub-line and every panel
   tagline; both are reset upright, matching the <em> rule above. */
:root[lang="ja"] .h-sub,  :root[lang="ko"] .h-sub,
:root[lang="ja"] .ap-tag, :root[lang="ko"] .ap-tag {
  font-style: normal;
}

/* CJK has no italic tradition — the site's decorative <em> accents
   should stay upright rather than being synthesised by the browser. */
:root[lang="ja"] em, :root[lang="ko"] em {
  font-style: normal;
}

/* ════════════════════════════════════════════════════════════════
   LOCALISATION-SPECIFIC ADJUSTMENTS

   Minimal, language-scoped corrections where a translated string
   demonstrably does not fit the existing layout. Not responsive
   redesign — each rule is inert in every other language.
   ════════════════════════════════════════════════════════════════ */

/* German. ".nav-back" sits between the nav links and #sf-sound-btn
   with roughly 11px of clearance in English. "← Galaxie" is one
   character longer; trimming the tracking recovers the difference so
   the desktop nav keeps its existing spacing. Below 769px .nav-back
   is display:none, so this only ever applies on desktop. */
:root[lang="de"] .nav-back {
  letter-spacing: 0.16em;
}

/* Homepage hero — release the shrink-to-fit cap.
   .hero-text is centred with `position:absolute; left:50%` plus a
   translateX(-50%). Because the box is laid out from the 50% offset to
   the right edge, its shrink-to-fit width can never exceed half the
   viewport — 625px at 1280px. English's longest headline line measures
   490px and just fits; Spanish (821px), Portuguese (877px) and Japanese
   (862px) do not, and .h-h1 wraps to four lines instead of the authored
   two.

   Giving the box an explicit centred width fixes every language at once
   without touching type sizes. English is unaffected: the content is
   text-align:center and .h-btns is justify-content:center, so a wider
   centred box paints the same pixels, and with no extra wrapping the
   box height — and therefore the translateY(-50%) origin — is unchanged.

   Above 769px only: below that, .h-btns switches to percentage widths
   (`.h-btns .btn-o{width:56%}`), so the container width is load-bearing
   for the mobile layout and must be left exactly as authored. */
@media (min-width: 769px) {
  :root .hero-text {
    width: min(92vw, 1040px);
  }
}

/* Homepage hero on phones (≤768px).
   Below 769px the hero box is min-content sized, so its width tracks the
   longest unbreakable word and the wrap behaviour is non-monotonic —
   Spanish measured two lines at 320px but four at 430px. Widening the
   box fixes it, but doing so for English was measured to collapse the
   English eyebrow from two lines to one and shift the buttons 15px.

   So the widening is applied to the seven non-English languages only.
   English keeps its authored mobile hero exactly as approved; the other
   languages get a container that can actually hold their headline. */
@media (max-width: 768px) {
  :root[lang="de"] .hero-text,
  :root[lang="es"] .hero-text,
  :root[lang="fr"] .hero-text,
  :root[lang="it"] .hero-text,
  :root[lang="pt"] .hero-text,
  :root[lang="ja"] .hero-text,
  :root[lang="ko"] .hero-text {
    width: 92vw;
  }
}

/* Display size for the same seven languages. Paired with the wider box
   above, this restores the authored two-line headline everywhere. */
@media (max-width: 768px) {
  :root[lang="de"] .h-h1,
  :root[lang="es"] .h-h1,
  :root[lang="fr"] .h-h1,
  :root[lang="it"] .h-h1,
  :root[lang="pt"] .h-h1 {
    font-size: clamp(1.7rem, 9vw, 3.2rem);
  }
}

/* Japanese and Korean hero display size — all widths.
   Full-width CJK glyphs are far denser than Latin at the same pixel
   size, so a smaller band reads as visually equal in weight while
   fitting eight glyphs on a line. This is normal CJK display sizing,
   not a compromise.

   It applies at every width, not just on phones: the authored clamp
   tops out at 8.5rem (136px), and eight glyphs at that size measure
   1088px — wider than the 1040px hero box — so Japanese wrapped at
   1600px too. One clamp covers 320px through 1600px. */
:root[lang="ja"] .h-h1,
:root[lang="ko"] .h-h1 {
  font-size: clamp(1.4rem, 6.6vw, 7rem);
}

/* Homepage nav — text expansion against the fixed ♪ control.
   The homepage nav has no "← Galaxy" button, so .nav-links sit at the
   far right while #sf-sound-btn is pinned inboard at right:20rem. The
   English label set leaves only ~25px of clearance; German, Spanish,
   French, Italian and Portuguese all run under the button.

   Tightening the gap and tracking recovers roughly 55px, which clears
   all five. English is deliberately excluded so its approved nav is
   untouched, and ja/ko are excluded because the CJK block above already
   gives them their own (tighter) tracking and they never collided.
   Below 769px .nav-links is display:none, so this is desktop-only.
   A new language that collides should be added to this list. */
@media (min-width: 769px) {
  :root[lang="de"] .nav-links,
  :root[lang="es"] .nav-links,
  :root[lang="fr"] .nav-links,
  :root[lang="it"] .nav-links,
  :root[lang="pt"] .nav-links {
    gap: 1.2rem;
  }
  :root[lang="de"] .nav-links a,
  :root[lang="es"] .nav-links a,
  :root[lang="fr"] .nav-links a,
  :root[lang="it"] .nav-links a,
  :root[lang="pt"] .nav-links a {
    letter-spacing: 0.13em;
  }
}

/* Homepage app-panel CTA links.
   The panel CTA is `<a class="ap-link">Label <span>→</span></a>`, and the
   page styles the arrow with `.ap-link:hover span{transform:translateX(4px)}`.
   Localising the label requires wrapping it in its own <span>, which would
   otherwise slide the label on hover too. Re-targeting the arrow in the
   page's own CSS would mean editing approved design rules, so the label
   span is excluded here instead — (0,3,1) beats the page's (0,2,1),
   no !important needed. */
.ap-link span[data-i18n],
.ap-link:hover span[data-i18n] {
  transform: none;
  transition: none;
}

/* Hero tagline, narrow-desktop band (901–1199px).
   Between those widths the hero is still a two-column grid but the
   text column has collapsed — 359px at 1024px — while the tagline is
   still set at .55em of a 7vw display size (39.4px). English's longest
   line measures 321px there, leaving only 38px of headroom, so every
   language with a longer line overflows the slot and wraps onto a
   third or fourth line: German +20px, Spanish +27px, Japanese +32px.

   Trimming the tagline to .48em in this band alone restores the
   designed two-line tagline in all eight languages. Outside the band
   nothing changes: from 1200px the column is wide enough at full size.

   The band deliberately stops at 901px. From 769–900px the column is
   so narrow that ENGLISH itself wraps to three lines — that is the
   site's own pre-existing behaviour, not a localisation defect, and
   shrinking type there would be a responsive redesign rather than a
   translation fix. Those widths are therefore left exactly as
   authored, and every language wraps there as English already did.

   NOTE: this also affects English and German, whose rendering was
   previously signed off. German was wrapping to four lines at 1024px
   — a real defect that the earlier pass's overflow-and-overlap checks
   did not measure. English already fitted and only becomes slightly
   smaller within the band. Flagged explicitly for review.

   CASCADE: this stylesheet is linked in <head> BEFORE each page's own
   inline <style>, so a rule here that matches an existing page class
   at equal specificity LOSES to the page. The `:root` prefix lifts
   this to (0,1,2) so it beats the page's `.hero-title span` (0,1,1).
   The :root[lang="…"] rules above are already (0,3,0) and win on
   their own. Keep this in mind when localising the other pages. */
@media (min-width: 901px) and (max-width: 1199px) {
  :root .hero-title span {
    /* .44em is set by the tightest point in the band, not by 1024px:
       the column is narrowest at ~950px (318px, vs 359px at 1024px)
       because the 5rem grid gap takes proportionally more room as the
       viewport shrinks. Spanish is the longest line at 346px there. */
    font-size: 0.44em;
  }
}

/* ════════════════════════════════════════════════════════════════
   STANDARD APP PAGES — CJK / HANGUL MICRO-LABEL COVERAGE

   The block far above resets the handful of class names the homepage
   and MyDay use for their small uppercase Latin devices. The seven
   standard pages carry roughly forty MORE such classes under their own
   names — .overline, .eyebrow, .world-no, .step-no, .vault-no,
   .journey-label, .screen-cap-title, .privacy-badge, .tone-chip and so
   on — every one set in the same idiom: 0.4rem–0.55rem, uppercase, and
   0.12em–0.40em of tracking.

   That idiom is built for Latin capitals. Applied to Japanese or
   Korean it produces 6–9px full-width glyphs pulled apart by up to
   0.4em: uppercase does nothing to CJK, the tracking breaks the visual
   word, and the size sits well below comfortable reading.

   Two groups, because they need different treatment:

   GROUP A — micro-labels. Casing reset, tracking cut to 0.06em, size
   lifted to 0.62rem. These sit on their own rows (eyebrows, captions,
   numbers, chips) where a few extra pixels of height cost nothing, and
   0.4rem CJK is genuinely unreadable.

   GROUP B — buttons and CTA links. Casing and tracking only. Their
   boxes are sized by padding around the label, so growing the type
   would change button geometry on pages that are already approved.
   Dropping 0.2em–0.28em of tracking already recovers more width than
   the translated string adds.

   DELIBERATELY EXCLUDED:
     · .footer-copy / .nbd-footer-copy — the © · Melbourne line is
       never translated, so it stays exactly as authored.
     · .starfoundry-credit — brand name only.
     · the social row's casing — it reads Instagram / X / TikTok /
       Email, and only the last is translated; lowercasing three brand
       names would be a visible change for no benefit. Its tracking
       alone is eased, further down.

   Every rule is :root[lang="ja"] / :root[lang="ko"] scoped, so English
   and the six Latin languages are untouched. Specificity is (0,3,0),
   which beats the pages' own (0,1,0) class rules even though this file
   is linked before their inline <style>.
   ════════════════════════════════════════════════════════════════ */

/* ── GROUP A: micro-labels ── */
:root[lang="ja"] .overline,            :root[lang="ko"] .overline,
:root[lang="ja"] .eyebrow,             :root[lang="ko"] .eyebrow,
:root[lang="ja"] .cta-eyebrow,         :root[lang="ko"] .cta-eyebrow,
:root[lang="ja"] .features-eyebrow,    :root[lang="ko"] .features-eyebrow,
:root[lang="ja"] .footer-label,        :root[lang="ko"] .footer-label,
:root[lang="ja"] .world-no,            :root[lang="ko"] .world-no,
:root[lang="ja"] .world-link,          :root[lang="ko"] .world-link,
:root[lang="ja"] .step-no,             :root[lang="ko"] .step-no,
:root[lang="ja"] .vault-no,            :root[lang="ko"] .vault-no,
:root[lang="ja"] .vault-sub,           :root[lang="ko"] .vault-sub,
:root[lang="ja"] .journey-label,       :root[lang="ko"] .journey-label,
:root[lang="ja"] .screen-cap-title,    :root[lang="ko"] .screen-cap-title,
:root[lang="ja"] .share-card-cap,      :root[lang="ko"] .share-card-cap,
:root[lang="ja"] .exp-callout-title,   :root[lang="ko"] .exp-callout-title,
:root[lang="ja"] .feat-title,          :root[lang="ko"] .feat-title,
:root[lang="ja"] .privacy-badge,       :root[lang="ko"] .privacy-badge,
:root[lang="ja"] .tone-chip,           :root[lang="ko"] .tone-chip,
:root[lang="ja"] .cs-pill,             :root[lang="ko"] .cs-pill,
:root[lang="ja"] .store-sub,           :root[lang="ko"] .store-sub,
:root[lang="ja"] .store-btn-sub,       :root[lang="ko"] .store-btn-sub,
:root[lang="ja"] .store-pill-sub,      :root[lang="ko"] .store-pill-sub,
/* our-story's footer link row is five product names plus one
   translated label, so the binding itself selects the only member
   that should change. */
:root[lang="ja"] .footer-links a[data-i18n],
:root[lang="ko"] .footer-links a[data-i18n],
:root[lang="ja"] .nbd-footer-link,     :root[lang="ko"] .nbd-footer-link,
:root[lang="ja"] .nbd-footer-tagline,  :root[lang="ko"] .nbd-footer-tagline {
  text-transform: none;
  letter-spacing: 0.06em;
  font-size: 0.62rem;
}

/* ── GROUP B: buttons and CTA links — casing and tracking only ── */
:root[lang="ja"] .btn-gold,            :root[lang="ko"] .btn-gold,
:root[lang="ja"] .btn-outline,         :root[lang="ko"] .btn-outline,
:root[lang="ja"] .btn-primary,         :root[lang="ko"] .btn-primary,
:root[lang="ja"] .btn-bronze,          :root[lang="ko"] .btn-bronze,
:root[lang="ja"] .btn-pearl,           :root[lang="ko"] .btn-pearl,
:root[lang="ja"] .btn-wisdom,          :root[lang="ko"] .btn-wisdom,
:root[lang="ja"] .btn-outline-wisdom,  :root[lang="ko"] .btn-outline-wisdom,
:root[lang="ja"] .btn-cs,              :root[lang="ko"] .btn-cs,
:root[lang="ja"] .btn-galaxy,          :root[lang="ko"] .btn-galaxy,
:root[lang="ja"] .footer-back,         :root[lang="ko"] .footer-back,
:root[lang="ja"] .footer-back-link,    :root[lang="ko"] .footer-back-link,
:root[lang="ja"] .cta-galaxy-link,     :root[lang="ko"] .cta-galaxy-link,
:root[lang="ja"] .cta-release,         :root[lang="ko"] .cta-release {
  text-transform: none;
  letter-spacing: 0.06em;
}

/* Social row: the platform names stay capitalised as authored; only
   the tracking is eased, so the translated "Email" does not sit with
   0.16em between its two or three CJK glyphs. */
:root[lang="ja"] .footer-social,       :root[lang="ko"] .footer-social,
:root[lang="ja"] .nbd-footer-social a, :root[lang="ko"] .nbd-footer-social a {
  letter-spacing: 0.08em;
}

/* Leading. These pages name their body copy differently from the
   homepage, so the existing .section-body / .hero-body / .feat-desc
   rule does not reach them, and CJK needs more room between lines than
   the site's tight Latin settings give it. */
:root[lang="ja"] .body-text,          :root[lang="ko"] .body-text,
:root[lang="ja"] .lead,               :root[lang="ko"] .lead,
:root[lang="ja"] .step-body,          :root[lang="ko"] .step-body,
:root[lang="ja"] .what-body,          :root[lang="ko"] .what-body,
:root[lang="ja"] .about-body,         :root[lang="ko"] .about-body,
:root[lang="ja"] .vault-body,         :root[lang="ko"] .vault-body,
:root[lang="ja"] .capture-desc,       :root[lang="ko"] .capture-desc,
:root[lang="ja"] .feeling-desc,       :root[lang="ko"] .feeling-desc,
:root[lang="ja"] .pp-desc,            :root[lang="ko"] .pp-desc,
:root[lang="ja"] .gp-desc,            :root[lang="ko"] .gp-desc,
:root[lang="ja"] .hero-feat-desc,     :root[lang="ko"] .hero-feat-desc,
:root[lang="ja"] .ritual-feat-desc,   :root[lang="ko"] .ritual-feat-desc,
:root[lang="ja"] .exp-callout-desc,   :root[lang="ko"] .exp-callout-desc,
:root[lang="ja"] .cs-note,            :root[lang="ko"] .cs-note,
:root[lang="ja"] .insights-list li,   :root[lang="ko"] .insights-list li,
:root[lang="ja"] .check-list li,      :root[lang="ko"] .check-list li {
  line-height: 1.95;
}

/* Display headings on these pages use their own class names too. */
:root[lang="ja"] .display,          :root[lang="ko"] .display,
:root[lang="ja"] .h2,               :root[lang="ko"] .h2,
:root[lang="ja"] .h1-display,       :root[lang="ko"] .h1-display,
:root[lang="ja"] .hero-headline,    :root[lang="ko"] .hero-headline,
:root[lang="ja"] .cta-display,      :root[lang="ko"] .cta-display,
:root[lang="ja"] .cta-title,        :root[lang="ko"] .cta-title,
:root[lang="ja"] .cta-headline,     :root[lang="ko"] .cta-headline,
:root[lang="ja"] .closing-title,    :root[lang="ko"] .closing-title,
:root[lang="ja"] .privacy-title,    :root[lang="ko"] .privacy-title,
:root[lang="ja"] .footer-title,     :root[lang="ko"] .footer-title,
:root[lang="ja"] .features-heading, :root[lang="ko"] .features-heading,
:root[lang="ja"] .step-title,       :root[lang="ko"] .step-title,
:root[lang="ja"] .gallery-title,    :root[lang="ko"] .gallery-title,
:root[lang="ja"] .cs-heading,       :root[lang="ko"] .cs-heading {
  line-height: 1.32;
}

/* The pages set font-style:italic on assorted accent lines. CJK has no
   italic, so the browser synthesises a slant; these are reset upright,
   matching the existing `em` rule. */
:root[lang="ja"] .hero-tagline-italic, :root[lang="ko"] .hero-tagline-italic,
:root[lang="ja"] .pull-quote,          :root[lang="ko"] .pull-quote,
:root[lang="ja"] .phil-quote,          :root[lang="ko"] .phil-quote,
:root[lang="ja"] .what-quote,          :root[lang="ko"] .what-quote,
:root[lang="ja"] .about-pull,          :root[lang="ko"] .about-pull,
:root[lang="ja"] .radioroom-accent,    :root[lang="ko"] .radioroom-accent,
:root[lang="ja"] .cta-accent,          :root[lang="ko"] .cta-accent,
:root[lang="ja"] .hero-accent,         :root[lang="ko"] .hero-accent,
:root[lang="ja"] .message-quote,       :root[lang="ko"] .message-quote,
:root[lang="ja"] .hero-calm,           :root[lang="ko"] .hero-calm {
  font-style: normal;
}

/* ════════════════════════════════════════════════════════════════
   STANDARD APP PAGES — MEASURED LOCALISATION CORRECTIONS

   Each rule below was added because a measurement across the seven
   pages x eight languages x fourteen widths matrix showed a specific
   translated string breaking a layout that English does not break.
   The measured numbers are quoted so the next person can re-derive
   the decision rather than guess at it.

   Every rule is :root[lang="…"]-scoped. English never sees any of it.
   ════════════════════════════════════════════════════════════════ */

/* ── 1. ".nav-back" running under the ambience control ──────────
   The app-page nav ends with "← Galaxy" hard against the right edge,
   with #sf-sound-btn pinned inboard at right:9.5rem. Measured left
   edge of .nav-back against the button's right edge of 1128px at
   1280px wide on moondrift:

       en  1138   +10px clear
       de  1137   + 9px clear   (already tightened, further below)
       es  1134   + 6px
       fr  1134   + 6px
       pt  1134   + 6px
       it  1126   − 2px  → OVERLAP
       ja  1149   +21px
       ko  1150   +22px

   Italian's "← Torna alla galassia" is the longest of the set and
   actually collides; Spanish, French and Portuguese sit at 6px, which
   is under half of English's clearance. Trimming the tracking from the
   authored 0.2em to 0.14em recovers roughly 10px across a 21-character
   label — enough to put all four back above English's own margin.

   This is the same device already applied to German on the homepage,
   extended to the other four expanding languages. German is left at
   its existing 0.16em: it measures 9px and needs nothing more.

   Not media-scoped on purpose. Most pages hide .nav-back below 769px,
   where the rule is simply inert; No Big Deal keeps it visible at every
   width and was measured at a 5px gap in Italian at 768px, which this
   same rule fixes. */
:root[lang="es"] .nav-back,
:root[lang="fr"] .nav-back,
:root[lang="pt"] .nav-back {
  letter-spacing: 0.14em;
}

/* Italian needs one more step. "← Torna alla galassia" is the longest
   label in the set, and 0.14em only recovered it to a 3px gap where
   the other three landed back on English's 9px. 0.11em takes it to
   roughly 8px — level with the rest — and is still comfortably inside
   the tracking range the nav already uses at its narrower breakpoints
   (the pages themselves drop to 0.14em under 900px and 0.1em under
   375px, so 0.11em is not a new visual idea). */
:root[lang="it"] .nav-back {
  letter-spacing: 0.11em;
}

/* ── 2. German compounds widening a content-sized grid track ────
   Moondrift's .features-grid is two content-sized columns on phones.
   The track is as wide as its widest unbreakable word, so a German
   compound drags the whole column out. Measured at 320px:

       en   card 154px, right column ends at 340 (20px past a 320
            viewport — the page's own pre-existing behaviour)
       de   card 167px, right column ends at 403 (83px past)

   "Traumdimensionen" is the culprit at 16 unbroken characters.

   The actual fix lives in the German pack, not here: a soft hyphen
   (U+00AD) sits at the morpheme boundary of the handful of compounds
   that land in these narrow slots — Traum­tagebuch, Traum­dimensionen,
   Sprach­aufnahme, Sprach­unterstützung, Unter­stützung. A soft hyphen
   is invisible until the browser needs the break, and because the
   break points are chosen by hand, no product name is ever split.
   That brought the German track from 167px back to 154px — the same
   width English uses — and the spill from 83px down to 25px, against
   English's own pre-existing 20px at this width.

   TRIED AND REJECTED: `overflow-wrap: anywhere`. It shrinks the track
   even further (126px, no spill at all) but breaks at arbitrary
   positions with no hyphen, and it mangled the product names —
   "DreamVa/ult", "DreamKe/eper", "Traumdi/mensione/n". Brand names
   surviving intact is worth more than the last 25px.

   The rule below is belt-and-braces for browsers that do ship a German
   hyphenation dictionary (the test Chrome did not, so it measured as a
   no-op); the soft hyphens carry the fix everywhere else. Phone widths
   only — from 430px up German measured no overflow at all. */
@media (max-width: 430px) {
  :root[lang="de"] .feat-name,
  :root[lang="de"] .feat-desc,
  :root[lang="de"] .capture-name,
  :root[lang="de"] .capture-desc {
    hyphens: auto;
    -webkit-hyphens: auto;
  }
}

/* ── 3. Our Story's hero display in Japanese and Korean ─────────
   .display is clamp(2.5rem, 10vw, 4rem) below 540px. At 320px that is
   32px, and full-width CJK glyphs at 32px need 256px for eight of
   them — more than the padded hero column holds, so the authored
   two-line headline measured four lines in both ja and ko while
   English stayed at two.

   The same reasoning and the same remedy as the homepage's .h-h1:
   CJK reads as visually heavier than Latin at equal pixel size, so a
   smaller band is not a compromise, it is normal CJK display sizing.
   Applied at every width for the same reason it was there — the
   authored clamp tops out at 4rem, which is still too wide for an
   eight-glyph line inside this column. */
:root[lang="ja"] .display,
:root[lang="ko"] .display {
  font-size: clamp(1.9rem, 7.4vw, 3.4rem);
}

/* ── 4. Unspoken's section headings in Italian and Portuguese ───
   "The words you carry / deserve a place to rest." is authored as two
   lines and holds at two in English at every width. Measured line
   counts for .section-title:

       1280px   en 2   de 3   es 3   fr 2   it 4   pt 4
       1600px   en 2   de 3   es 3   fr 2   it 4   pt 4

   Italian and Portuguese double it on full-size desktop, which is a
   visible change to the section rhythm rather than an artefact of a
   narrow screen. Trimming the top of the clamp from 3.2rem to 2.7rem
   restores three lines without touching the phone sizes, where the
   heading legitimately wraps further in every language including
   English. German and Spanish are left alone at three lines — one
   extra line is ordinary text expansion, not a defect.

   Measured again after the trim: Italian is back to English's two
   lines at 1200px and up, Portuguese to three. Portuguese was still
   measuring four at 1024px, where the clamp is driven by 4vw rather
   than its ceiling, so its band starts at 901px — the point below
   which the column narrows enough that every language, English
   included, legitimately wraps further. */
@media (min-width: 1200px) {
  :root[lang="it"] #what .section-title {
    font-size: clamp(2rem, 4vw, 2.7rem);
  }
}
@media (min-width: 901px) {
  :root[lang="pt"] #what .section-title {
    font-size: clamp(2rem, 3.4vw, 2.7rem);
  }
}

/* ── 5. Wisdom's hero headline on phones, German and Italian ────
   .hero-headline is clamp(2.8rem, 5.5vw, 4.4rem), so between 361 and
   430px it sits on its 2.8rem floor and cannot shrink with the
   viewport. Measured line counts:

       320px   en 5   de 6   es 6   fr 5   it 5   pt 3
       375px   en 3   de 5   es 4   fr 4   it 5   pt 3
       390px   en 3   de 3   es 3   fr 4   it 5   pt 3
       430px   en 3   de 3   es 3   fr 4   it 4   pt 3

   German at 375 and Italian at 375–390 run two lines past English on
   the single most prominent element on the page, which pushes the
   download buttons well down the screen. Lowering the floor for those
   two in that band brings them back to four. 320px is deliberately
   left alone: English itself takes five lines there, so every language
   wrapping further is the page's own behaviour, not a translation
   defect.

   NOT DONE HERE, and reported instead: whispers' #ritual .h2 measures
   en 3 / de 4 / fr 4 at 1280px. A one-line delta on a heading English
   already wraps is ordinary text expansion, and an earlier attempt to
   trim it shrank approved desktop typography without fixing the case
   that actually stands out (de 2→4 at 430px, where the clamp is
   already on its floor). Left for a human call. */
@media (min-width: 361px) and (max-width: 430px) {
  :root[lang="de"] .hero-headline,
  :root[lang="it"] .hero-headline {
    font-size: clamp(2.2rem, 5.5vw, 4.4rem);
  }
}

/* ── 6. CJK text sitting under an inline style attribute ────────
   A handful of elements on these pages carry their typography in a
   `style=""` attribute rather than a class. Inline styles beat every
   stylesheet rule regardless of specificity, so the CJK block above
   cannot reach them, and they were measured still rendering Japanese
   and Korean at 7.0–7.5px with 0.20em–0.35em of Latin tracking:

     easyspeak  the closing "← Back to the Galaxy" link
     whispers   the same link in its CTA
     moondrift  the footer's "A Starfoundry World" eyebrow

   plus four places where an inline `font-style:italic` makes the
   browser synthesise a slant on CJK, which the rest of this file is
   careful to avoid.

   `!important` is used here and nowhere else in this stylesheet: an
   inline style genuinely cannot be overridden any other way. The
   elements are addressed through their own i18n binding rather than a
   class, because the styling is inline precisely because these
   elements have no class to hang a rule on — and it keeps the rule
   obviously tied to the translated text it exists for. */

:root[lang="ja"] [data-i18n="common.cta.backToGalaxyArrow"],
:root[lang="ko"] [data-i18n="common.cta.backToGalaxyArrow"],
:root[lang="ja"] [data-i18n="common.eyebrow.starfoundryWorld"],
:root[lang="ko"] [data-i18n="common.eyebrow.starfoundryWorld"] {
  font-size: 0.62rem !important;
  letter-spacing: 0.06em !important;
  text-transform: none !important;
}

:root[lang="ja"] [data-i18n="moondrift.cta.titleB"],
:root[lang="ko"] [data-i18n="moondrift.cta.titleB"],
:root[lang="ja"] [data-i18n="moondrift.cta.sub"],
:root[lang="ko"] [data-i18n="moondrift.cta.sub"],
:root[lang="ja"] [data-i18n="unspoken.what.momentTitleB"],
:root[lang="ko"] [data-i18n="unspoken.what.momentTitleB"],
:root[lang="ja"] [data-i18n="unspoken.about.sig"],
:root[lang="ko"] [data-i18n="unspoken.about.sig"] {
  font-style: normal !important;
}

/* ── 7. No Big Deal's nav links against its own ambience control ─
   This is the page's own furniture, not the selector — but the
   translations make an existing English condition materially worse,
   so it belongs here.

   No Big Deal hides .nav-links at 640px rather than 768px like the
   other app pages, so just above that breakpoint the bar carries the
   links while #sf-sound-btn is still pinned at right:9.5rem. Measured
   overlap of .nav-links by the ♪ button:

       641px   en 13   ja 19   it 28   de 34
       660px   en  3   ja 10   it 18   de 29
       680px   en  0   ja  0   it  8   de 19
       700px   en  0   ja  0   it  0   de  9
       720px   everything clear

   English already tucks under by 13px at 641px — that is the page's
   authored behaviour and is left alone. What is fixed here is the
   translations turning a 13px graze into a 34px overlap and dragging
   the affected band 60px wider.

   Same device as the homepage nav rule far above: trim the flex gap
   and the tracking for the expanding languages. Together those recover
   roughly 37px across the three links, which clears German — the
   worst case — with room to spare.

   The band is deliberately 641–768px. Every other page has
   .nav-links display:none across it, so this rule is inert for them;
   from 769px up the bar has room in every language. */
@media (min-width: 641px) and (max-width: 768px) {
  :root[lang="de"] .nav-links,
  :root[lang="es"] .nav-links,
  :root[lang="fr"] .nav-links,
  :root[lang="it"] .nav-links,
  :root[lang="pt"] .nav-links,
  :root[lang="ja"] .nav-links,
  :root[lang="ko"] .nav-links {
    gap: 1.1rem;
  }
  :root[lang="de"] .nav-links a,
  :root[lang="es"] .nav-links a,
  :root[lang="fr"] .nav-links a,
  :root[lang="it"] .nav-links a,
  :root[lang="pt"] .nav-links a,
  :root[lang="ja"] .nav-links a,
  :root[lang="ko"] .nav-links a {
    letter-spacing: 0.12em;
  }
}

/* ── 8. Tickle's own class names ────────────────────────────────
   Tickle names its furniture differently again (.ft-*), so the CJK
   blocks above do not reach it. Audited against the page's own CSS,
   three classes carry the small-uppercase-Latin idiom AND receive
   translated text:

       .ft-tagline   0.42rem uppercase 0.16em   "Tiny apps from a small galaxy."
       .ft-link      0.42rem uppercase 0.16em   Back to the Galaxy / Privacy / Terms / Support
       .ft-social a  0.42rem uppercase 0.14em   Instagram / X / TikTok / Email

   .nav-back, .nav-links a and .store-pill-sub are already covered by
   the shared blocks. .ft-copy is deliberately excluded — it is the
   © · Melbourne line, which is never translated.

   .ft-social a gets tracking only, for the same reason as every other
   social row on the site: three of its four labels are platform brand
   names and lowercasing them would be a visible change for no gain. */
:root[lang="ja"] .ft-tagline, :root[lang="ko"] .ft-tagline,
:root[lang="ja"] .ft-link,    :root[lang="ko"] .ft-link {
  text-transform: none;
  letter-spacing: 0.06em;
  font-size: 0.62rem;
}

:root[lang="ja"] .ft-social a, :root[lang="ko"] .ft-social a {
  letter-spacing: 0.08em;
}

/* Leading and heading rhythm for Tickle's body copy, matching what the
   other worlds get. Its display sizes are already modest clamps, so
   only the line-height needs adjusting — no size change is required
   and none is made. */
:root[lang="ja"] .hero-copy,   :root[lang="ko"] .hero-copy,
:root[lang="ja"] .screens-sub, :root[lang="ko"] .screens-sub,
:root[lang="ja"] .cta-sub,     :root[lang="ko"] .cta-sub {
  line-height: 1.95;
}

:root[lang="ja"] .screens-heading, :root[lang="ko"] .screens-heading,
:root[lang="ja"] .cta-heading,     :root[lang="ko"] .cta-heading {
  line-height: 1.4;
}
