
/* ===================================================================
   R2O — Concept C: "Immersive brand world"
   Design plan (per k-uid-frontend-design brainstorm -> plan -> critique):

   Palette (traces to r2o-corporate-design SKILL.md Section 1/5.1 only):
     --r2o-navy #005D95   world anchor / deep end of gradient
     --r2o-teal #00A295   wave crest / CTA fill / brand accent
     --r2o-sky  #039CFF   secondary highlight — crest hairline only, sparing
     --r2o-white #FFFFFF  headline / device chrome / high-contrast layer
     --r2o-panel #F4F8F9  light continuation section below hero
     --r2o-ink  #1A2533   body text, light-section only, never on gradient

   Type: Roboto per SKILL 3.1 (system-sans fallback stack, self-contained,
   no font-loading per task constraint) for Latin/numerals; Myanmar system
   stack for the real Burmese copy, which IS the hero's primary language.
   Weights 400/700 only, per SKILL 3.1.

   Web-extension flag (Ulric proposes, Daniel/brand owner to confirm):
   SKILL 5.1's --fs-cover-title / --fs-stat clamps target a 1280px deck
   slide. This is a full-bleed 1440-wide marketing hero, a viewport class
   the brand skill doesn't cover yet. I scale the SAME family/weight/
   letter-spacing rules to a larger clamp ceiling for hero-scale type,
   rather than inventing a new type system. Flagged, not silently done.

   Signature move (the one deliberate risk, per k-uid-frontend-design):
   SKILL 2.4 documents R2O's own original 2020 wave motif — a navy base
   layer + thinner teal accent stripe — as a corner decoration. This
   concept takes that exact two-layer relationship (same colors, same
   proportion logic) and scales it up until it stops being a footer and
   becomes the hero's actual layout skeleton: headline lives in the "sky"
   above the crest, the device and the real stats ride physically on the
   crest. Nothing invented — the brand's own wave, made structural.
   Everything else (type scale, button shape, spacing) stays disciplined
   and un-experimental so the wave stays the one loud move.

   Layout (ASCII):
   +---------------------------------------------------------+
   | [wordmark, white, no button]                             |
   |                                                           |
   |  EYEBROW                                                  |
   |  Headline (Burmese, real copy)              [phone device]|
   |  Subhead paragraph                            rides the   |
   |  [ CTA pill -> #apply ]                       wave crest  |
   |                                                           |
   |  ~~~ navy back wave (scaled 2020 motif) ~~~~~~~~~~~~~~~~ |
   |   ~~~ teal crest stripe ~~~~ sky hairline ~~~~~~~~~~~~~~ |
   |    [ real stat trio riding directly on the crest fill ]  |
   +---------------------------------------------------------+
   =================================================================== */

:root {
  --r2o-navy:   #005D95;
  --r2o-teal:   #00A295;
  --r2o-sky:    #039CFF;
  --r2o-coral:  #FF715B;
  --r2o-coral-tint: #FFF0EE;
  --r2o-white:  #FFFFFF;
  --r2o-ink:    #1A2533;
  --r2o-muted:  #6B8FA3;
  --r2o-panel:  #F4F8F9;
  --r2o-border: #BDD3DB;

  --r2o-cover-gradient: linear-gradient(135deg, var(--r2o-navy) 0%, var(--r2o-teal) 100%);

  --font-latin:   "Roboto", -apple-system, "Segoe UI", Arial, Helvetica, sans-serif;
  /* NAMED GAP — myanmar-typography-ssot.md D11, 2026-08-28.
     §1b of that SSOT prescribes a self-hosted subset,
     _knowledge/typography/fonts/NotoSansMyanmar-subset-my-400-700.woff2,
     and an @font-face block that leads the stack with it. That directory
     does not exist and neither does the file, so the @font-face block is
     unshippable as written and is deliberately absent here. These pages
     therefore run on system fonts only.

     What that costs: on a device with no Myanmar font the page falls
     through to sans-serif and the script does not render. Android has
     shipped Noto Sans Myanmar since Android 5, which is why the risk is
     small rather than zero, and it is why Noto leads the stack below.

     Not ours to close. Mack builds the subset, Barmee re-verifies its
     shaping and ink span, Daniel owns the OFL question. Do not invent a
     replacement and do not paste §1b's @font-face in until the file exists.

     Canonical Myanmar stack. Verbatim from myanmar-typography-ssot.md §1.
     Owner: barmee (K-LOC). Do not write a per-artifact stack here. */
  --font-my:
    "Noto Sans Myanmar",
    "Noto Sans Myanmar UI",
    "Pyidaungsu",
    "Myanmar Text",
    "Padauk",
    "Myanmar MN",
    "Myanmar Sangam MN",
    sans-serif;

  /* Hero-scale extension of SKILL 5.1 clamps — flagged above */
  --fs-eyebrow:     0.85rem;
  --fs-hero-title:  clamp(2.15rem, 3.6vw, 3.55rem);
  --fs-subhead:     clamp(1rem, 1.3vw, 1.15rem);
  --fs-stat-num:    clamp(1.7rem, 2.3vw, 2.5rem);
  /* 13.6px, not 11.2px. Measured below the 13.3px rendered floor at
     desktop, and this label is Myanmar script, where the marks above and
     below the base are what carry the meaning. */
  --fs-stat-label:  0.85rem;

  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-12: 3rem;

  --radius-pill: 999px;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font-my), var(--font-latin);
  color: var(--r2o-ink);
  background: var(--r2o-panel);
  -webkit-font-smoothing: antialiased;
  /* The 1.50 floor as a default rather than a per-element fix. Anything
     that forgets to set line-height now lands on the floor instead of on
     `normal`, which for Noto Sans Myanmar computes to ~2.184em (hhea
     ascender 1324 / descender -860 over 1000 upem). Measured, not
     assumed: before this line, .hero-cta, .stat-label and .info-step all
     reported line-height:normal in Chrome at 375px. */
  line-height: 1.5;
}
[lang="en"],
.latin {
  font-family: var(--font-latin);
}

/* FOCUS INDICATOR. Was 3px solid var(--r2o-sky) #039CFF, which fails
   WCAG 2.2 SC 1.4.11 (3:1 for a focus indicator) on every surface these
   pages have. Measured in Chrome: 2.92:1 on white, 2.55:1 on the teal end
   of the hero gradient, 1.89:1 on the lime submit button. Independently
   recomputed 2026-09-02; fix approved by Daniel the same day, while none
   of the six pages is live yet.

   Two tone, both halves brand tokens, because no single colour clears 3:1
   on all of white, panel, navy, the gradient and lime at once:
     - a 3px white halo immediately around the element
     - a 3px navy outline outside it, in the gap outline-offset opens
   Navy carries the light surfaces (7.00:1 on white, 6.55:1 on panel) and
   the lime button (4.40:1). White carries the dark ones (7.00:1 on navy,
   3.18:1 on the teal end of the gradient). Whatever the ring lands on,
   one of its halves clears 3:1. Same ring as lp-stk-catalog.html, so the
   seven pages do not each have their own. */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, summary:focus-visible {
  outline: 3px solid var(--r2o-navy);
  outline-offset: 3px;
  box-shadow: 0 0 0 3px var(--r2o-white);
}
/* .hero-cta carries a drop shadow of its own. The rule above would replace
   it on focus, so the button would visibly flatten the moment it is
   tabbed to. Restated with both layers rather than dropped. */
.hero-cta:focus-visible {
  box-shadow: 0 0 0 3px var(--r2o-white), 0 14px 32px rgba(0,20,40,0.28);
}
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ===================== HEADER ===================== */
.topbar {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  padding: 30px 64px 0;
}
.wordmark {
  display: inline-block;
  text-decoration: none;
  line-height: 0;
}
.wordmark img {
  display: block;
  height: 30px;
  width: auto;
}

/* ===================== HERO — the wave world ===================== */
.hero {
  position: relative;
  min-height: 900px;
  overflow: hidden;
  background: var(--r2o-cover-gradient);
  display: flex;
  flex-direction: column;
}

/* atmospheric glow blobs — soft, brand-hue only, restrained */
.hero-glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(2px);
  pointer-events: none;
  z-index: 0;
}
.hero-glow--a { width: 620px; height: 620px; top: -220px; left: -160px; background: radial-gradient(circle, rgba(255,255,255,0.10) 0%, rgba(255,255,255,0) 70%); }
.hero-glow--b { width: 520px; height: 520px; top: 120px; right: -140px; background: radial-gradient(circle, rgba(3,156,255,0.16) 0%, rgba(3,156,255,0) 70%); }

/* readability scrim over the copy column — same hue family, not a new color */
.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 0;
  /* Measured, not styled. White 15.4px on the teal end of the 135deg
     cover gradient came out at 3.18:1, against a 4.5:1 requirement for
     body text. The old scrim faded to zero at 62%, which is precisely
     where the gradient is lightest. It now carries opacity all the way
     across; the hue is unchanged (same 0,29,51 as before), so the hero
     still reads as the same artifact, only legible. */
  background: linear-gradient(115deg, rgba(0,29,51,0.52) 0%, rgba(0,29,51,0.42) 42%, rgba(0,29,51,0.34) 100%);
  pointer-events: none;
}

.hero-inner {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  padding: 148px 64px 0;
  max-width: 1440px;
  margin: 0 auto;
  width: 100%;
}

.hero-copy {
  width: 56%;
  max-width: 640px;
  min-width: 0;
  padding-bottom: 40px;
}
.hero-eyebrow {
  font-family: var(--font-latin);
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--r2o-white);
  padding-top: 4px;         /* padding floor, never eaten by centering */
  margin: 0 0 var(--space-6) 0;
}
.hero-title {
  font-size: var(--fs-hero-title);
  font-weight: 700;
  line-height: 1.5;
  color: var(--r2o-white);
  margin: 0 0 var(--space-6) 0;
  max-width: 600px;
}
.hero-sub {
  font-family: var(--font-my), var(--font-latin);
  font-size: var(--fs-subhead);
  line-height: 1.85;
  color: rgba(255,255,255,0.92);
  margin: 0 0 var(--space-8) 0;
  max-width: 540px;
}
.hero-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--r2o-white);
  color: var(--r2o-navy);
  font-family: var(--font-my), var(--font-latin);
  font-weight: 700;
  font-size: 1rem;
  padding: 17px 30px;
  border-radius: var(--radius-pill);
  text-decoration: none;
  box-shadow: 0 14px 32px rgba(0,20,40,0.28);
  transition: transform .18s ease, box-shadow .18s ease;
}
.hero-cta:hover { transform: translateY(-2px); box-shadow: 0 18px 40px rgba(0,20,40,0.34); }
.hero-cta svg { flex-shrink: 0; }

/* ===================== DEVICE ARTWORK =====================
   The hero device is a photograph (.phone-mockup__image), and everything
   below it here is what remains live: the platform glow under it.

   REMOVED 2026-08-28 — the entire CSS/SVG phone mockup: .device,
   -frame, -notch, -screen, -screen-head, -brand, -dot, -card,
   -card-label, -card-value, -bar, -terms, -term, -term--active, -cta,
   -home. Fifteen rules, 130 lines, ZERO of them referenced by any
   markup. They are dead in concept-c-wave.html too, left behind when the
   drawn device was replaced by the photo.

   Three of them drew the tenure chooser (.device-terms / .device-term /
   .device-term--active) inside that fake screen. Daniel, 2026-08-28:
   "Na prvni LP jsme tenures vyndali. Na ostatnich to udelame taky." The
   live page removed the real field in f9e3d4b; this removes the styling
   that survived it, so no future page can wire markup back onto a rule
   that is still sitting here.
   ========================================================== */

/* device platform glow — sits under the phone, on the crest */
.device-glow {
  position: absolute;
  right: -30px; top: 420px;
  width: 320px; height: 180px;
  background: radial-gradient(ellipse, rgba(255,255,255,0.22) 0%, rgba(255,255,255,0) 70%);
  z-index: 1;
  pointer-events: none;
}
.phone-mockup {
  position: absolute;
  right: 96px;
  top: 10px;
  width: min(29vw, 340px);
  z-index: 3;
  pointer-events: none;
}
.phone-mockup__image {
  display: block;
  width: 100%;
  height: auto;
}

/* ===================== WAVE — the scaled-up brand motif ===================== */
.hero-wave {
  position: relative;
  z-index: 1;
  margin-top: -260px;
  pointer-events: none;
}
.hero-wave svg { display: block; width: 100%; height: 460px; }

/* ===================== STAT TRIO — riding the crest, real content ===================== */
.hero-stats {
  position: relative;
  z-index: 4;
  margin-top: -152px;
  padding: 0 64px 56px;
}
.stat-band {
  max-width: 1312px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* Measured: 4.48:1 for the number and 3.53:1 for the label at the
     light end of this overlay, both short of 4.5:1. Deepened until both
     clear it. Same colour, more of it. */
  background: linear-gradient(90deg, rgba(0,32,56,0.58), rgba(0,32,56,0.46));
  backdrop-filter: blur(2px);
}
.stat {
  text-align: center;
  padding: 26px 12px;
  border-right: 1px solid rgba(255,255,255,0.18);
}
.stat:last-child { border-right: none; }
/* Two tiles (Samsung and PRO 1 in v1, coverage tile withheld): a quantity
   query on the children, no :has(). Each tile takes a column and a half of
   the three, so the pair fills the band in equal halves. Three tiles never
   match this selector and render exactly as before. */
.stat:first-child:nth-last-child(2),
.stat:first-child:nth-last-child(2) ~ .stat {
  width: 150%;
}
.stat:first-child:nth-last-child(2) ~ .stat {
  margin-left: 50%;
}
.stat-num {
  /* Myanmar stack first: this slot holds a place name on every variant
     (ရန်ကုန် today, two or five cities on the campaign pages). */
  font-family: var(--font-my), var(--font-latin);
  font-size: var(--fs-stat-num);
  font-weight: 700;
  color: var(--r2o-white);
  /* 1.5, not 1. The coverage stat wraps to two lines the moment a page
     covers more than one city, and 1 collides the clusters. */
  line-height: 1.5;
}
.stat-num small { font-size: 0.55em; font-weight: 700; }
.stat-label {
  font-family: var(--font-my), var(--font-latin);
  font-size: var(--fs-stat-label);
  font-weight: 700;
  /* Full white. At 0.82 the label measured 3.53:1; the 18% saved nothing
     that a reader in Yangon benefits from. */
  color: var(--r2o-white);
  letter-spacing: 0.02em;
  margin-top: 8px;
}

/* ===================== LIGHT CONTINUATION SECTION ===================== */
.section {
  max-width: 1312px;
  margin: 0 auto;
  padding: var(--space-12) 64px;
}
.section--brands {
  max-width: 1120px;
}
.section-eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--r2o-teal);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: var(--space-2);
}
.section-title-wrap {
  display: flex;
  align-items: stretch;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}
.section-bar { width: 4px; background: var(--r2o-teal); flex-shrink: 0; }
.section-title {
  font-family: var(--font-my), var(--font-latin);
  font-size: clamp(1.25rem, 1.8vw, 1.6rem);
  font-weight: 700;
  color: var(--r2o-navy);
  margin: 0;
  line-height: 1.5;
  overflow-wrap: break-word;
}

/* ===================== CONTENT PANELS — Moe Zaw revision ===================== */
.content-panel {
  max-width: 1120px;
  margin: 0 auto var(--space-8);
  padding: var(--space-12) 64px;
  background: var(--r2o-white);
  border-top: 4px solid var(--r2o-teal);
}
.content-panel__head {
  display: flex;
  align-items: stretch;
  gap: var(--space-3);
  margin-bottom: var(--space-8);
}
.content-panel__bar {
  width: 4px;
  background: var(--r2o-teal);
  flex-shrink: 0;
}
.content-panel__title {
  font-family: var(--font-my), var(--font-latin);
  font-size: clamp(1.35rem, 2.1vw, 1.9rem);
  font-weight: 700;
  line-height: 1.55;
  color: var(--r2o-navy);
  margin: 0;
  overflow-wrap: break-word;
}
.info-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-8);
}
.info-step {
  display: grid;
  grid-template-columns: 44px 1fr;
  gap: var(--space-4);
}
.info-step__badge {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--r2o-navy);
  color: var(--r2o-white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-latin);
  font-weight: 700;
}
.info-step__details { min-width: 0; padding-top: 2px; }
.info-step__summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 30px;
  align-items: center;
  gap: var(--space-4);
  min-height: 44px;
  cursor: pointer;
  font-family: var(--font-my), var(--font-latin);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.55;
  color: var(--r2o-navy);
  list-style: none;
}
.info-step__summary::-webkit-details-marker { display: none; }
.info-step__summary::marker { content: ""; }
.info-step__summary-title {
  min-width: 0;
  overflow-wrap: break-word;
}
.info-step__plus {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--r2o-border);
  position: relative;
  color: var(--r2o-navy);
}
.info-step__plus::before,
.info-step__plus::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 12px;
  height: 2px;
  background: currentColor;
  transform: translate(-50%, -50%);
}
.info-step__plus::after { transform: translate(-50%, -50%) rotate(90deg); }
.info-step__details[open] .info-step__plus::after { transform: translate(-50%, -50%) scaleX(0); }
.info-step__content { padding-top: var(--space-3); }
.info-step__text,
.warning-body,
.channels-intro,
.brand-copy,
.form-reassurance,
.form-trust-note {
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.96rem;
  line-height: 1.75;
  overflow-wrap: break-word;
}
.info-step__text {
  margin: 0 0 var(--space-2);
  color: var(--r2o-ink);
}
.info-step__text:last-child { margin-bottom: 0; }
.info-step__text strong { font-weight: 700; }
.warning-body {
  margin: 0;
  color: var(--r2o-ink);
}
.warning-card {
  background: var(--r2o-coral-tint);
  border-left: 4px solid var(--r2o-coral);
  padding: 24px 26px;
}
#safety {
  max-width: 1120px;
  padding-left: 0;
  padding-right: 0;
}
.warning-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--r2o-ink);
  margin: 0 0 12px;
  line-height: 1.6;
}
.warning-title .warning-icon { color: var(--r2o-coral); }
.warning-card .warning-body {
  font-size: 0.88rem;
  line-height: 1.9;
}
.channels-intro {
  margin: 0 0 var(--space-8);
  text-align: center;
}
.channel-row {
  display: grid;
  grid-template-columns: repeat(7, minmax(72px, 1fr));
  gap: var(--space-3);
  list-style: none;
  margin: 0;
  padding: 0;
}
.channel-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  color: var(--r2o-navy);
  font-family: var(--font-latin);
  font-weight: 700;
  /* Measured 11.52px at 375 px. The link box is 158 px wide there, two per
     row, so nothing was constraining it — it was just small, on the block
     whose entire job is proving the page is the real R2O. Raised to the
     same 13.6 px floor the stat labels were raised to. */
  font-size: 0.85rem;
}
.channel-icon {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--r2o-navy);
  display: flex;
  align-items: center;
  justify-content: center;
}
.channel-icon svg {
  width: 20px;
  height: 20px;
}
.brand-copy {
  margin: 0;
  color: var(--r2o-ink);
}
.brand-strip {
  max-width: 1120px;
  margin: var(--space-8) auto 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  list-style: none;
  padding: 0;
}
.brand-strip__item,
.brand-strip__other {
  border: 1px solid var(--r2o-border);
  color: var(--r2o-navy);
  background: var(--r2o-white);
  font-family: var(--font-latin);
  font-weight: 700;
  font-size: 0.84rem;
  padding: 10px 14px;
}
.brand-strip__other {
  font-family: var(--font-my), var(--font-latin);
  /* Muted on white measures 3.45:1 at 13.4 px — the third place in this
     stylesheet where the brand's caption grey fails AA (footer 3.23, the
     partner host line 3.23). The chip still has to read as secondary to the
     named brands, so the de-emphasis moves from colour to WEIGHT: same navy
     as the other chips, regular instead of bold. Navy on white = 5.1:1.
     Flagged to Daniel as a brand-skill gap, not fixed by inventing a hue. */
  color: var(--r2o-navy);
  font-weight: 400;
}

/* ===================== APPLY FORM ===================== */
.apply {
  background: var(--r2o-navy);
  padding: var(--space-12) 64px;
}
.apply-inner { max-width: 620px; margin: 0 auto; }
.apply-title {
  font-family: var(--font-my), var(--font-latin);
  font-size: clamp(1.3rem, 1.8vw, 1.6rem);
  font-weight: 700;
  color: var(--r2o-white);
  line-height: 1.6;
  margin: 0 0 var(--space-8) 0;
  overflow-wrap: break-word;
}
.field { margin-bottom: var(--space-6); }
.field label {
  display: block;
  font-family: var(--font-my), var(--font-latin);
  /* 14px, not 12.8px. Measured below the 13.3px readable floor, and this
     is the form the page exists for. */
  font-size: 0.875rem;
  line-height: 1.6;
  font-weight: 700;
  color: rgba(255,255,255,0.78);
  margin-bottom: var(--space-2);
}
.field input,
.field select {
  width: 100%;
  padding: 14px 16px;
  /* 1.4.11: a form field's boundary is a non-text element that has to
     reach 3:1 against what surrounds it. 0.28 white on navy did not. */
  border: 1px solid rgba(255,255,255,0.65);
  background: rgba(255,255,255,0.06);
  color: var(--r2o-white);
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.92rem;
  line-height: 1.5;
  border-radius: 0;
  appearance: none;
}
.field input::placeholder { color: rgba(255,255,255,0.80); }
/* Pevná předvolba 09. Není to placeholder ani přednastavená hodnota, kterou
   jde smazat: je to část pole, kterou nelze editovat. Drží formát a zároveň
   ukazuje, že se sem píšou latinské číslice. */
.phone-input {
  display: flex;
  align-items: stretch;
  /* Same 1.4.11 boundary contrast as .field input; this composite field
     is a form field too and was still on the old value. */
  border: 1px solid rgba(255,255,255,0.65);
  background: rgba(255,255,255,0.06);
}
/* Same two-tone ring as the shared rule above, on the wrapper rather
   than the inner input, because the prefix and the input are one field. */
.phone-input:focus-within {
  outline: 3px solid var(--r2o-navy);
  outline-offset: 3px;
  box-shadow: 0 0 0 3px var(--r2o-white);
}
.phone-input__prefix {
  display: flex;
  align-items: center;
  padding: 14px 12px 14px 16px;
  font-family: var(--font-latin);
  font-size: 0.92rem;
  line-height: 1.5;
  font-weight: 700;
  color: var(--r2o-white);
  border-right: 1px solid rgba(255,255,255,0.28);
  user-select: none;
}
.phone-input input {
  border: none;
  background: transparent;
  flex: 1;
  min-width: 0;
  font-family: var(--font-latin);
  letter-spacing: 0.04em;
}
/* The ring belongs to the wrapper. Without cancelling the halo too, the
   shared rule would draw a second ring around the inner input and the
   field would show two. */
.phone-input input:focus-visible { outline: none; box-shadow: none; }
.field select option { color: var(--r2o-ink); }
.field-select {
  position: relative;
}
.field-select .chevron {
  position: absolute;
  right: 14px;
  top: 50%;
  width: 16px;
  height: 16px;
  transform: translateY(-50%);
  pointer-events: none;
}
/* ---- CLOSED CHOICE (radio group) + SECONDARY FIELD LINK ------------
   2026-10-30, ATOM: township became a required pick of three areas, and
   both the area and the model field got an exit link for a visitor the
   pilot does not cover. Built from the field tokens above so a choice row
   reads as the same control family as the inputs: same 0.65 white
   boundary (1.4.11), same 0.06 fill, square corners. */
.choice-group { border: 0; margin: 0; padding: 0; min-width: 0; }
.choice-group__legend {
  /* Same type as .field label: the legend is this field's label. */
  display: block;
  padding: 0;
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.875rem;
  line-height: 1.6;
  font-weight: 700;
  color: rgba(255,255,255,0.78);
  margin-bottom: var(--space-2);
}
.choice-group__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
}
/* Three across once a row fits all three labels without wrapping. */
@media (min-width: 560px) {
  .choice-group__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.field .choice {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 52px;
  margin: 0;
  padding: 12px 16px;
  border: 1px solid rgba(255,255,255,0.65);
  background: rgba(255,255,255,0.06);
  color: var(--r2o-white);
  font-size: 0.92rem;
  font-weight: 400;
  cursor: pointer;
}
.field .choice:hover { background: rgba(255,255,255,0.12); }
.field .choice:has(input:checked) {
  border-color: var(--r2o-white);
  background: rgba(255,255,255,0.16);
}
.choice-group[aria-invalid="true"] .choice {
  border-color: var(--r2o-coral);
  background: rgba(255,113,91,0.10);
}
.choice input[type="radio"] {
  appearance: none;
  flex: none;
  width: 20px;
  height: 20px;
  margin: 0;
  padding: 0;
  border: 2px solid var(--r2o-white);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
}
/* The checked dot is a gradient, not a box-shadow, so the shared focus
   ring (which is a box-shadow halo) never replaces it. */
.choice input[type="radio"]:checked {
  background: radial-gradient(circle, var(--r2o-white) 0 5px, transparent 5.5px);
}
.choice__text {
  font-family: var(--font-my), var(--font-latin);
  line-height: 1.6;
  min-width: 0;
  overflow-wrap: break-word;
}
.field-alt {
  /* Secondary action on the navy form. Outline, not fill: the filled navy
     .partner-cta would vanish into this section, and anything filled
     competes with the one lime submit. inline-block for the same reason as
     .partner-cta: the Burmese label stays one inline run and the line
     breaker, not flex, decides where it wraps. */
  display: inline-block;
  position: relative;
  max-width: 100%;
  margin-top: var(--space-3);
  padding: 10px 44px 10px 20px;
  border: 1px solid rgba(255,255,255,0.65);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--r2o-white);
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 1.6;
  text-decoration: none;
  overflow-wrap: break-word;
}
/* Measured 2026-10-30 at 375 px: the area label needs 346 px on one line
   in a 327 px column, so it wraps. Left to the dictionary breaker it broke
   inside a phrase (and text-wrap: balance split a word from its particle).
   The generator wraps each space-separated phrase in .field-alt__phrase,
   markup only, so the label can break at Moe Zaw's own spaces and nowhere
   else. */
.field-alt__phrase { white-space: nowrap; }
.field-alt svg { position: absolute; right: 20px; top: 50%; transform: translateY(-50%); }
.field-alt:hover { background: rgba(255,255,255,0.12); border-color: var(--r2o-white); }
.apply-submit {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  /* THE ONE LIME ELEMENT ON THE PAGE.
     r2o-corporate-design 1.1.1, approved exception, Daniel 2026-07-26:
     lime is the primary CTA fill on customer-facing landing pages, and
     only there, and only as a field behind dark text.

     This is a visible change from the live Yangon page, which fills this
     button with teal. Teal measured 3.18:1 for white on #00A295 at
     15.2px bold, against 4.5:1. Lime with Ink on it measures 10.06:1.
     The exception exists for exactly this: the page's one action has to
     win against a saturated coral warning block, and teal is already a
     structural colour here so a teal button reads as more structure.

     To revert to the live page's teal, swap the two declarations below
     back to var(--r2o-teal) / var(--r2o-white) and re-run the contrast
     check, because that reverts an AA failure too. */
  background: #B1E101;
  color: var(--r2o-ink);
  font-family: var(--font-my), var(--font-latin);
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.5;
  padding: 16px 30px;
  border: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  margin-top: var(--space-2);
}
.form-reassurance,
.form-trust-note {
  margin: var(--space-4) 0 0;
  color: rgba(255,255,255,0.88);
}
.form-trust-note strong { font-weight: 700; }

/* --- form states (added with the real form; SSOT: line-height always set,
       never break-all on Myanmar) --- */
.apply-form { margin: 0; }
.field input[aria-invalid="true"],
.field select[aria-invalid="true"] {
  border-color: var(--r2o-coral);
  background: rgba(255,113,91,0.10);
}
.field__error {
  font-family: var(--font-my), var(--font-latin);
  /* 14px, not 12.8px. Measured below the 13.3px readable floor, and this
     is the one string a confused person actually has to read. It only
     shows once validation has failed, which is why the earlier sweeps
     did not see it: nothing was in an error state at the time. */
  font-size: 0.875rem;
  line-height: 1.6;
  font-weight: 700;
  color: #FFC9C0;
  margin: var(--space-2) 0 0;
  overflow-wrap: break-word;
}
.form-status {
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.9rem;
  line-height: 1.75;
  margin: var(--space-4) 0 0;
  padding: 14px 16px;
  color: var(--r2o-white);
  border-left: 4px solid var(--r2o-coral);
  background: rgba(255,113,91,0.14);
  overflow-wrap: break-word;
}
.apply-submit[aria-disabled="true"] { opacity: 0.6; cursor: progress; }
/* Verifying state (2026-10-21): a submit made before the Turnstile token
   exists is queued and sent by itself once the token arrives (lp.js).
   The button is disabled against a double send but must not look dead,
   so it keeps full strength (Ink on lime, 10.06:1) instead of the 0.6
   used while the request itself is in flight, and carries a progress
   mark. Without motion (reduced-motion) the mark is a static ring and the
   label carries the meaning. */
.apply-submit.is-verifying { opacity: 1; cursor: progress; }
.apply-submit__spinner {
  flex: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid rgba(26,37,51,0.25);   /* --r2o-ink at 25 % */
  border-top-color: var(--r2o-ink);
}
@media (prefers-reduced-motion: no-preference) {
  .apply-submit__spinner { animation: r2o-spin 0.9s linear infinite; }
  @keyframes r2o-spin { to { transform: rotate(360deg); } }
}
.apply-submit__label { overflow-wrap: break-word; min-width: 0; }
/* Hint, not error: "tap the box above" while the interactive checkbox is
   on screen. Same box as .form-status, teal instead of coral, the way the
   success box marks a non-error state. */
.form-status--hint {
  border-left-color: var(--r2o-teal);
  background: rgba(0,162,149,0.16);
}
.apply-success {
  border-left: 4px solid var(--r2o-teal);
  background: rgba(0,162,149,0.16);
  padding: 24px 26px;
  margin-bottom: var(--space-6);
}
.apply-success__text {
  font-family: var(--font-my), var(--font-latin);
  font-size: 1rem;
  line-height: 1.75;
  font-weight: 700;
  color: var(--r2o-white);
  margin: 0;
  overflow-wrap: break-word;
}
/* honeypot: off-screen, never display:none (bots skip hidden fields) */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ===================== FOOTER ===================== */
.footer {
  border-top: 1px solid var(--r2o-border);
  padding: var(--space-6) 64px;
  display: flex;
  align-items: center;
  gap: 10px;
  /* Muted measured 3.23:1 on the panel at 11.5px. Small print is still
     text. Navy on the same panel clears 4.5:1 and stays a brand token. */
  color: var(--r2o-navy);
  font-size: 0.85rem;
}
.footer .wordmark img { height: 22px; }

/* ===================== MOTION — respectful of reduced-motion ===================== */
@media (prefers-reduced-motion: no-preference) {
  .reveal-up {
    animation: r2o-rise 0.8s cubic-bezier(.2,.7,.3,1) both;
  }
  .reveal-up--1 { animation-delay: .05s; }
  .reveal-up--2 { animation-delay: .16s; }
  .reveal-up--3 { animation-delay: .27s; }
  .reveal-up--4 { animation-delay: .38s; }
  @keyframes r2o-rise {
    from { opacity: 0; transform: translateY(22px); }
    to   { opacity: 1; transform: translateY(0); }
  }
}

/* ===================== RESPONSIVE — desktop hero is the graded artifact;
   this keeps mobile from breaking without chasing mobile detail. ===================== */
@media (max-width: 980px) {
  .topbar { padding: 22px 24px 0; }
  .wordmark img { height: 24px; }
  .hero { min-height: 0; }
  .hero-inner { flex-direction: column; padding: 108px 24px 0; }
  .hero-copy { width: 100%; max-width: none; }
  .hero-title {
    max-width: 100%;
    font-size: clamp(1.72rem, 7vw, 2.15rem);
    line-height: 1.5;
  }
  .hero-sub {
    max-width: 100%;
  }
  .hero-device-col { display: none; }
  .hero-wave { margin-top: 40px; }
  .hero-wave svg { height: 220px; }
  .hero-stats { margin-top: -110px; padding: 0 24px 40px; }
  .stat-num { font-size: 1.4rem; }
  .section, .content-panel, .apply, .footer { padding-left: 24px; padding-right: 24px; }
  .content-panel { margin-bottom: var(--space-6); }
  .warning-card { padding: 20px 18px; }
  #safety { padding-left: 24px; padding-right: 24px; }
  .channel-row { grid-template-columns: repeat(3, minmax(72px, 1fr)); }
}
@media (max-width: 520px) {
  .hero-inner { padding-left: 20px; padding-right: 20px; }
  .hero-title {
    max-width: 100%;
    font-size: 1.72rem;
    line-height: 1.5;
  }
  .hero-sub {
    max-width: 100%;
    font-size: 0.96rem;
  }
  .hero-stats { padding-left: 20px; padding-right: 20px; }
  /* Stack instead of shrink. Three across at 375px forced the label to
     9.3px (measured); stacked, both lines are readable and the coverage
     value has room for two city names. */
  .stat-band { grid-template-columns: 1fr; }
  .stat {
    padding: 16px 18px;
    min-width: 0;
    border-right: none;
    border-bottom: 1px solid rgba(255,255,255,0.18);
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-4);
    text-align: left;
  }
  .stat:last-child { border-bottom: none; }
  .stat:first-child:nth-last-child(2),
  .stat:first-child:nth-last-child(2) ~ .stat { width: auto; margin-left: 0; }
  .stat-num { font-size: 1.15rem; }
  .stat-label { margin-top: 0; text-align: right; }
  .hero-stats { margin-top: -80px; }
  .info-step { grid-template-columns: 36px 1fr; gap: var(--space-3); }
  /* 0.82rem measured 13.12px, just under the 13.3 px floor the rest of
     the page was raised to. */
  .info-step__badge { width: 36px; height: 36px; font-size: 0.85rem; }
  .info-step__summary {
    grid-template-columns: 30px minmax(0, 1fr);
    gap: var(--space-3);
  }
  .info-step__plus { grid-column: 1; grid-row: 1; }
  .info-step__summary-title {
    grid-column: 2;
    grid-row: 1;
    font-size: 0.94rem;
    line-height: 1.65;
  }
  .channel-row { grid-template-columns: repeat(2, minmax(72px, 1fr)); }
}

/* ===================================================================
   CAMPAIGN EXTENSIONS
   Everything above this line is concept-c-wave.html verbatim, with only
   the three documented corrections from myanmar-typography-ssot.md
   (canonical --font-my token, no cluster-breaking properties, 1.5 floor).
   Everything below is new, and exists because the archived Wix campaign
   pages need structure the live Yangon phone page never had.
   Every value still resolves to an r2o-corporate-design token.
   =================================================================== */

/* ---- OFFER CARD ---------------------------------------------------
   One highlighted promotion inside the light section. Today only the
   Samsung page has one ("Weekend Special 0% downpayment", Fri/Sat/Sun).
   Teal-tinted field rather than a new colour: SKILL 1.2 teal tint.
   Rendered only when the variant declares `offer`. ------------------ */
.offer-card {
  max-width: 1120px;
  margin: var(--space-8) auto 0;
  background: #E0F4F2;                 /* SKILL 1.2 teal tint */
  border-left: 4px solid var(--r2o-teal);
  padding: 28px 30px;
}
.offer-card__eyebrow {
  font-family: var(--font-latin);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #007A6E;                      /* SKILL 1.5 dark teal anchor */
  line-height: 1.5;
  margin: 0 0 var(--space-2);
}
.offer-card__title {
  font-family: var(--font-my), var(--font-latin);
  font-size: clamp(1.1rem, 1.6vw, 1.4rem);
  font-weight: 700;
  color: var(--r2o-navy);
  line-height: 1.5;
  margin: 0 0 var(--space-3);
  overflow-wrap: break-word;
}
.offer-card__body {
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.92rem;
  color: var(--r2o-ink);
  line-height: 1.85;
  margin: 0;
  overflow-wrap: break-word;
}
.offer-card__list {
  margin: var(--space-3) 0 0;
  padding-left: 1.25em;
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.92rem;
  color: var(--r2o-ink);
  line-height: 1.85;
}
.offer-card__list li { margin-bottom: var(--space-2); overflow-wrap: break-word; }
.offer-card__list li:last-child { margin-bottom: 0; }

/* ---- PARTNER CATALOGUE STEP ---------------------------------------
   The structural difference the archived pages actually carry, and the
   reason this is a template rather than six copies. On r2omercury,
   pro1products and stksolarbattery the visitor CANNOT complete the form
   without first leaving to a partner catalogue and choosing an item.
   That step has to be a real, prominent outbound link and the form has
   to gain a product field. The phone pages have neither.
   ------------------------------------------------------------------ */
.partner-step {
  max-width: 1120px;
  margin: var(--space-8) auto 0;
  background: var(--r2o-panel);
  border-left: 4px solid var(--r2o-navy);
  padding: 28px 30px;
}
.partner-step__title {
  font-family: var(--font-my), var(--font-latin);
  font-size: clamp(1.05rem, 1.5vw, 1.3rem);
  font-weight: 700;
  color: var(--r2o-navy);
  line-height: 1.5;
  margin: 0 0 var(--space-3);
  overflow-wrap: break-word;
}
.partner-step__body {
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.92rem;
  color: var(--r2o-ink);
  line-height: 1.85;
  /* Pro 1 and STK carry the whole apply sequence here as four and five
     source paragraphs, so the gap BETWEEN paragraphs has to be smaller
     than the gap before the catalogue button, or the button stops
     reading as the end of the block. */
  margin: 0 0 var(--space-4);
  overflow-wrap: break-word;
}
/* :last-of-type would not work here: the last <p> in the block is the
   host line or the missing-link marker, not a body paragraph. The extra
   room goes on the action itself instead. */
.partner-step .partner-cta { margin-top: var(--space-2); }
.partner-step__no-link { margin: var(--space-2) 0 0; }
.partner-cta {
  /* inline-block, NOT inline-flex (2026-09-20, measured at 375 px on
     lp-mercury). The label is mixed script and arrives as raw HTML: a
     Myanmar text node, a <span lang="en">, another Myanmar text node.
     Under flex each of those became its own flex item, so the label broke
     into three side-by-side columns that wrapped independently, and the
     partner name split mid-word. As ordinary inline content the whole
     label is one run and the Burmese dictionary decides the breaks.
     The arrow's spacing moves from `gap` to the svg rule below. */
  display: inline-block;
  background: var(--r2o-navy);
  color: var(--r2o-white);
  font-family: var(--font-my), var(--font-latin);
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.5;
  padding: 15px 28px;
  border-radius: var(--radius-pill);
  text-decoration: none;
  overflow-wrap: break-word;
}
/* The arrow is pinned to the right edge and centred, with room reserved
   for it in the padding. Left inline it orphaned onto a line of its own
   whenever the label filled the row exactly (measured: Mercury at 375 px). */
.partner-cta { position: relative; padding-right: 52px; }
.partner-cta svg { position: absolute; right: 28px; top: 50%; transform: translateY(-50%); }
.partner-cta:hover { background: #004a78; }
.partner-cta__host {
  font-family: var(--font-latin);
  /* Measured 12.48px. It names the domain the visitor is about to be sent
     to, which is a trust signal on a page that carries an anti-scam block;
     it does not get to be the smallest thing on the page. */
  font-size: 0.85rem;
  font-weight: 400;
  /* Measured 3.23:1 in Muted on the panel — the same failure the footer had
     and the same brand-token fix. It names the domain the visitor is about
     to be sent to, on a page that carries an anti-scam block, so it is not
     a place to be under AA. */
  color: var(--r2o-navy);
  line-height: 1.5;
  margin: var(--space-3) 0 0;
  word-break: normal;
  overflow-wrap: break-word;
}

/* ---- TRANSLATION GAP MARKER ---------------------------------------
   A string that has no approved Burmese source is shown AS MISSING, per
   r2o-corporate-design Language §Layer 2: English is never a fallback.
   Loud on purpose. Nothing ships to a customer with one of these on it.
   ------------------------------------------------------------------ */
.i18n-gap {
  display: inline-block;
  font-family: var(--font-latin);
  font-size: 0.78rem;
  font-weight: 700;
  line-height: 1.5;
  color: #7A2016;
  background: var(--r2o-coral-tint);
  border: 2px dashed var(--r2o-coral);
  border-radius: 16px;                 /* SKILL 2.1 --radius-input */
  padding: 6px 12px;
}

/* ---- HERO WITHOUT A DEVICE ----------------------------------------
   The phone mockup is a real photograph of a phone. On the solar,
   furniture and shopping-mall variants it would be the wrong object, and
   this project does not ship a stand-in. The copy column takes the full
   width instead and the hero stays intact. ------------------------- */
.hero--no-device .hero-copy { width: 100%; max-width: 900px; }
.hero--no-device .hero-device-col { display: none; }

@media (max-width: 980px) {
  .offer-card, .partner-step { padding: 22px 18px; }
}

/* ---- SUBMIT ARROW -------------------------------------------------
   The inline SVG in the button carries stroke="#FFFFFF" from the live
   page, where the button was teal. On lime a white arrow disappears.
   Recoloured here rather than in the template so the button and its
   glyph can never disagree. ---------------------------------------- */
.apply-submit svg path { stroke: var(--r2o-ink); }

/* ---- SKIP LINK ----------------------------------------------------
   Absent from the live page and flagged as missing on 2026-08-26. The
   apply form sits below five accordion panels, a warning block and a
   seven-item channel row: reaching it by keyboard without this is a long
   walk. Hidden until focused, then a real, visible target. ---------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
}
.skip-link:focus {
  left: 12px;
  top: 12px;
  width: auto;
  height: auto;
  clip: auto;
  clip-path: none;
  display: inline-block;
  background: var(--r2o-white);
  color: var(--r2o-navy);
  font-family: var(--font-my), var(--font-latin);
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.5;
  padding: 12px 20px;
  border-radius: var(--radius-pill);
  text-decoration: none;
  box-shadow: 0 10px 28px rgba(0,20,40,0.3);
}

/* The promotion's lead block. Reads as the card's opening statement
   without claiming to be a heading, because on the Samsung page its
   headline and its body are a single approved-pending string. */
.offer-card__body--lead {
  font-size: 1rem;
  font-weight: 700;
  color: var(--r2o-navy);
  margin-top: var(--space-4);
}

/* ===================== STK IN-PAGE PRODUCT LIST (2026-09-24) =====================
   Rendered by the last block of lp.js, on lp-stk.html only. Every selector
   is scoped to .lp-products / .lp-product / .product-choice, none of which
   exists on the other five pages, so nothing here reaches them.

   DIRECTION. This is a lead page, not a shop: the list exists so the
   visitor can point at the unit they want and move on to the form. So the
   card is compact and horizontal, photo beside identity, and the price is
   the loudest thing on it, as on the catalogue page (a rent-to-own buyer
   decides on the number). Six cards show first; the rest open in place.
   Measured reason for compact: the catalogue's vertical card is 536px
   tall at 375px, which would put 34 products at about 24 phone screens.

   No lime: the one lime element on this page is the form's submit button
   (SKILL 1.1.1 landing-page exception, "one lime element per page"). Card
   CTAs are navy like .partner-cta. Radius per SKILL 2.1's landing-page
   scale: 30px card (20px below 420px), 16px inline callout, pill CTA. */
.lp-products {
  max-width: 1120px;
  margin: var(--space-6) auto 0;
  text-align: center;          /* centres only the show-all button */
}
.lp-products__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
  /* stretch: cards in one row are one height, the CTA pins to the bottom. */
  align-items: stretch;
  text-align: left;
}
@media (min-width: 640px) {
  .lp-products__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
}
@media (min-width: 1000px) {
  .lp-products__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.lp-product {
  --lp-card-radius: 30px;
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr);
  grid-template-areas:
    "fig   ident"
    "specs specs"
    "cta   cta";
  grid-template-rows: auto 1fr auto;
  column-gap: var(--space-4);
  padding: var(--space-4);
  background: var(--r2o-white);
  border: 1px solid var(--r2o-border);
  border-radius: var(--lp-card-radius);
  box-shadow: 0 2px 10px rgba(0, 20, 40, 0.06);
  transition: box-shadow 0.25s cubic-bezier(.2,.7,.3,1), border-color 0.2s ease;
}
.lp-product[hidden] { display: none; }
@media (hover: hover) {
  .lp-product:hover { box-shadow: 0 12px 28px rgba(0, 20, 40, 0.12); }
}
.lp-product:focus-within { box-shadow: 0 12px 28px rgba(0, 20, 40, 0.12); }
/* The picked card. Border weight and colour, no fill change, so the photo
   plate stays white. 2px inset via box-shadow keeps the geometry still. */
.lp-product.is-selected {
  border-color: var(--r2o-navy);
  box-shadow: inset 0 0 0 1px var(--r2o-navy), 0 12px 28px rgba(0, 20, 40, 0.12);
}

.lp-product__figure {
  grid-area: fig;
  margin: 0;
  align-self: start;
  width: 104px;
  aspect-ratio: 1 / 1;
  border-radius: 16px;
  background: var(--r2o-white);
  border: 1px solid var(--r2o-panel);
  overflow: hidden;
}
/* contain, never cover: supplier cut-outs of tall batteries and wide
   inverters (measured subject aspect 0.57 to 2.39 on the catalogue). */
.lp-product__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 6px;
}
.lp-product__image.is-placeholder { padding: 0; object-fit: cover; }

.lp-product__ident {
  grid-area: ident;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  font-family: var(--font-latin);
}
.lp-product__meta {
  margin: 0;
  font-size: 0.83rem;
  font-weight: 700;
  line-height: 1.4;
  color: var(--r2o-navy);
  letter-spacing: 0.02em;
}
.lp-product__meta span + span::before {
  content: "\00B7";
  margin: 0 0.45em;
  color: var(--r2o-muted);
}
.lp-product__name {
  margin: 0;
  font-family: var(--font-latin);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.35;
  color: var(--r2o-ink);
  overflow-wrap: anywhere;
}
.lp-product__price {
  margin: 4px 0 0;
  font-size: 1.35rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--r2o-navy);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}

/* Spec drawer. Collapsed, as on the catalogue and the Wix source. Its
   label is the spec block's own first line ("Specification"). */
.lp-product__specs,
.lp-product__spec-single {
  grid-area: specs;
  align-self: end;
  margin: var(--space-3) 0 0;
  border-top: 1px solid var(--r2o-panel);
  font-family: var(--font-latin);
}
.lp-product__specs-summary {
  display: grid;
  grid-template-columns: 1fr 20px;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;            /* WCAG 2.2 SC 2.5.8, comfortable not minimum */
  cursor: pointer;
  list-style: none;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--r2o-navy);
}
.lp-product__specs-summary::-webkit-details-marker { display: none; }
.lp-product__specs-summary::marker { content: ""; }
.lp-product__specs-summary:focus-visible { border-radius: 8px; }
.lp-product__plus { position: relative; width: 20px; height: 20px; justify-self: end; }
.lp-product__plus::before,
.lp-product__plus::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 12px; height: 2px;
  background: var(--r2o-teal);
  transform: translate(-50%, -50%);
  transition: transform 0.2s ease;
}
.lp-product__plus::after { transform: translate(-50%, -50%) rotate(90deg); }
.lp-product__specs[open] .lp-product__plus::after { transform: translate(-50%, -50%) scaleX(0); }
.lp-product__spec-list {
  list-style: none;
  margin: 0 0 var(--space-2);
  padding: 0;
  font-size: 0.83rem;
  line-height: 1.6;
  color: var(--r2o-ink);
}
.lp-product__spec-list li {
  padding: 5px 0;
  border-bottom: 1px solid var(--r2o-panel);
  overflow-wrap: anywhere;
}
.lp-product__spec-list li:last-child { border-bottom: 0; }
.lp-product__spec-single {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--r2o-navy);
}

.lp-product__cta {
  grid-area: cta;
  align-self: end;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 48px;
  margin-top: var(--space-3);
  padding: 12px 20px;
  background: var(--r2o-navy);
  color: var(--r2o-white);
  font-family: var(--font-latin);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-decoration: none;
  border-radius: var(--radius-pill);
  transition: background 0.2s ease;
}
.lp-product__cta:hover { background: #004A78; }
.lp-product__cta svg { flex-shrink: 0; }
/* When a product has no spec block, the CTA still needs air above it. */
.lp-product__ident + .lp-product__cta { margin-top: var(--space-4); }

/* Show-all: the page's own catalogue-link button, reused as a local
   control. The outbound arrow is removed in JS, so its reserved padding
   goes too; the count sits where the arrow sat. */
.lp-products__more.partner-cta {
  margin-top: var(--space-6);
  padding: 15px 28px;
  border: 0;
  cursor: pointer;
  text-align: center;
}
.lp-products__more-count {
  display: inline-block;
  margin-left: 0.6em;
  padding: 1px 10px;
  border-radius: var(--radius-pill);
  background: var(--r2o-white);
  color: var(--r2o-navy);
  font-family: var(--font-latin);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}
.lp-products__more[hidden] { display: none; }
/* The catalogue link steps aside while the in-page list is shown. Its own
   display:inline-block would otherwise beat the hidden attribute. */
#choose .partner-cta[hidden],
#choose .partner-cta__host[hidden] { display: none; }

/* Loading skeleton: the card's real geometry, so nothing jumps. */
.lp-product--skeleton .lp-product__figure { background: var(--r2o-panel); border: 0; }
.lp-skel {
  display: block;
  height: 12px;
  width: 100%;
  margin-top: 8px;
  border-radius: 6px;
  background: var(--r2o-panel);
}
.lp-skel--short { width: 45%; margin-top: 4px; }
.lp-skel--price { width: 62%; height: 22px; }

/* One authored moment: the list arrives once, as a whole. */
@media (prefers-reduced-motion: no-preference) {
  .lp-products.is-ready .lp-products__grid {
    animation: lp-products-in 0.5s cubic-bezier(.2,.7,.3,1) both;
  }
  @keyframes lp-products-in {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }
  }
}

@media (max-width: 420px) {
  .lp-product {
    --lp-card-radius: 20px;
    grid-template-columns: 88px minmax(0, 1fr);
    column-gap: var(--space-3);
  }
  .lp-product__figure { width: 88px; }
  .lp-product__price { font-size: 1.2rem; }
}

/* ---- PICKED PRODUCT, SHOWN BACK IN THE FORM ----------------------
   Sits on the navy .apply section as a white inline callout (radius 16,
   SKILL 2.1). Photo, name and price exactly as the feed gives them. */
.product-choice {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: 0 0 var(--space-6);
  padding: 10px 14px 10px 10px;
  background: var(--r2o-white);
  border-radius: 16px;
  font-family: var(--font-latin);
}
.product-choice[hidden] { display: none; }
.product-choice__figure {
  flex: 0 0 56px;
  width: 56px;
  height: 56px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--r2o-white);
}
.product-choice__figure .lp-product__image { padding: 2px; }
.product-choice__text { display: flex; flex-direction: column; min-width: 0; }
.product-choice__name {
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.35;
  color: var(--r2o-ink);
  overflow-wrap: anywhere;
}
.product-choice__price {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--r2o-navy);
  font-variant-numeric: tabular-nums;
}

/* ===================================================================
   PARTNER CO-BRAND PAGE BLOCKS (ATOM x Rent2Own, 2026-10-15)
   All optional, all rendered only when a variant declares them
   (cobrand, steps, crossLink, info.lead, apply.lead, faq). No existing
   page uses any of these classes, so nothing above changes for them.
   Every value is an r2o-corporate-design token already declared in :root.
   =================================================================== */

/* ---- CO-BRAND HEADER ----------------------------------------------
   The partner's wordmark is dark-on-light and has no reversed version on
   file, so it cannot sit on the dark hero the way the white R2O wordmark
   does (ATOM navy on the hero navy is a near-invisible mark). The header
   therefore becomes an in-flow white band carrying both marks in their own
   colours, and the hero starts below it. Hairline divider, no box. */
.topbar--cobrand {
  position: relative;
  background: var(--r2o-white);
  padding: 18px 64px;
  gap: 20px;
  border-bottom: 1px solid var(--r2o-border);
}
.topbar--cobrand .wordmark img { height: 28px; }
.cobrand-divider {
  width: 1px;
  height: 32px;
  background: var(--r2o-border);
  flex-shrink: 0;
}
/* Optical match, not equal box heights: the ATOM file carries its chevron
   mark above and below the letters, so its box is taller than its type.
   At 36 px the ATOM letters land at the R2O wordmark's cap height. */
.cobrand-partner {
  display: block;
  height: 36px;
  width: auto;
}
/* The header no longer overlays the hero, so the hero's own top padding
   (148 / 108 px, sized to clear an absolute header) shrinks by the
   header's height. */
.hero--cobrand .hero-inner { padding-top: 72px; }
/* The device photo is placed 10 px from the top of the hero, which on the
   overlay-header pages is behind the transparent header. Under an in-flow
   white band that left it 14 px from the band's edge (measured at 1280),
   so it moves down to the headline's line and its glow moves with it. */
.hero--cobrand .phone-mockup { top: 56px; }
.hero--cobrand .device-glow { top: 466px; }
.hero--cobrand .hero-sub + .hero-sub {
  /* The second line is a lead-in to the button, not a new paragraph. */
  margin-top: calc(-1 * var(--space-4));
}

/* ---- HOW IT WORKS: three numbered steps on the page surface ------- */
.how-steps { max-width: 1120px; padding-bottom: var(--space-8); }
.how-steps__lead {
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.96rem;
  line-height: 1.75;
  color: var(--r2o-ink);
  max-width: 720px;
  margin: 0 0 var(--space-8);
  overflow-wrap: break-word;
}
.how-steps__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-8);
}
.how-step {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
}
.how-step__body { min-width: 0; }
.how-step__title {
  font-family: var(--font-my), var(--font-latin);
  font-size: 1.02rem;
  font-weight: 700;
  line-height: 1.6;
  color: var(--r2o-navy);
  margin: 6px 0 var(--space-2);
  overflow-wrap: break-word;
}
.how-step__text {
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.92rem;
  line-height: 1.8;
  color: var(--r2o-ink);
  margin: 0;
  overflow-wrap: break-word;
}

/* ---- CROSS LINK: "not for you? here is the page that is" ----------
   Hairline rules above and below, no tinted field. The button is the
   navy outbound pill already used for the partner catalogue link, so it
   stays visibly secondary to the white hero CTA and the lime submit. */
.cross-link { max-width: 1120px; padding-top: 0; }
.cross-link__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  padding: var(--space-6) 0;
  border-top: 1px solid var(--r2o-border);
  border-bottom: 1px solid var(--r2o-border);
}
.cross-link__text {
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.96rem;
  line-height: 1.75;
  color: var(--r2o-ink);
  margin: 0;
  min-width: 0;
  overflow-wrap: break-word;
}
.cross-link__text strong { font-weight: 700; color: var(--r2o-navy); }
.cross-link__cta { flex-shrink: 0; }

/* ---- OPTIONAL LEAD LINES ------------------------------------------ */
.content-panel__lead {
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.96rem;
  line-height: 1.75;
  color: var(--r2o-ink);
  margin: calc(-1 * var(--space-4)) 0 var(--space-8);
  overflow-wrap: break-word;
}
.apply-lead {
  font-family: var(--font-my), var(--font-latin);
  font-size: 0.96rem;
  line-height: 1.75;
  color: var(--r2o-white);
  margin: calc(-1 * var(--space-6)) 0 var(--space-8);
  overflow-wrap: break-word;
}

/* ---- FAQ AFTER THE FORM: the info panel's component, own spacing --- */
.content-panel--faq { margin-top: var(--space-12); }

@media (max-width: 980px) {
  .topbar--cobrand { padding: 14px 24px; gap: 14px; }
  /* 24, not smaller: the wordmark is the page's "to top" link, and WCAG
     2.2 SC 2.5.8 wants a 24 px target (measured 22 px at 375 on the first
     pass). Same height as the production mobile wordmark. */
  .topbar--cobrand .wordmark img { height: 24px; }
  .cobrand-divider { height: 28px; }
  .cobrand-partner { height: 31px; }
  .hero--cobrand .hero-inner { padding-top: 40px; }
  .how-steps__list { grid-template-columns: 1fr; gap: var(--space-6); }
  .cross-link__inner { flex-direction: column; align-items: flex-start; }
  .content-panel--faq { margin-top: var(--space-8); }
}
@media (max-width: 520px) {
  .how-step { grid-template-columns: 36px minmax(0, 1fr); gap: var(--space-3); }
  .how-step__title { margin-top: 3px; }
}

/* ---- HERO PHOTO (ATOM, 2026-10-15) ----------------------------------
   Replaces the device photo on pages that set hero.photo. Same treatment
   as the cover of the September management deck (.cover-photo /
   .cover-veil in r2o-decks/2026-10-01-r2o-monthly-marketing-report-
   september-2026.html): brand navy underneath, the photo at .62 opacity,
   a navy veil dense on the text side and open on the motif side, plus a
   bottom fade so the photo runs into the wave instead of ending on an
   edge. The photo is graded to the deck cover by prepare-hero-photo.py.
   The glow blobs and the copy scrim are off: the veil does their job. */
.hero--photo { background: var(--r2o-navy); }
.hero--photo .hero-glow,
.hero--photo .hero-scrim { display: none; }
.hero-photo {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 100% 30%;
  opacity: .62;
  pointer-events: none;
}
.hero-photo-veil {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    linear-gradient(0deg, rgba(0,93,149,.86) 0%, rgba(0,93,149,.40) 13%, rgba(0,93,149,0) 26%),
    linear-gradient(90deg, #005D95 0%, rgba(0,93,149,.96) 30%, rgba(0,93,149,.70) 52%,
      rgba(0,93,149,.24) 74%, rgba(0,93,149,0) 100%);
}
.hero--photo .hero-copy { width: 52%; max-width: 620px; }

@media (max-width: 980px) {
  /* Phone: the copy spans the full width, so a full-height photo would put
     the face behind the headline. The photo sits below the button instead. */
  /* Measured at 375: the space between the button and the wave crest was
     136 px, so the wave cut her at the chin and hid the phone. Photo pages
     get 120 px more above the wave, and the photo box is anchored to the
     hero's BOTTOM in px (wave + stat band have a fixed height, the copy
     above does not), so face and phone land between button and crest.
     Its top and bottom fade out in the image itself (mask), so it starts
     and ends as navy instead of on an edge; the full-hero veil is off. */
  .hero--photo .hero-wave { margin-top: 160px; }
  .hero-photo {
    top: auto;
    bottom: 225px;
    height: 400px;
    object-position: 100% 30%;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 22%, #000 70%, transparent 100%);
            mask-image: linear-gradient(180deg, transparent 0%, #000 22%, #000 70%, transparent 100%);
  }
  .hero-photo-veil { display: none; }
  .hero--photo .hero-copy { width: 100%; max-width: none; }
}
