/* ═════════════════════════════════════════════════════════════════════════════
   ORO · MOBILE & TABLET EXPERIENCE LAYER
   Loaded LAST. Namespaced `orom-`. Nothing here changes the desktop render:
   every rule either lives inside `@media (max-width: 1024px)` or targets an
   element that only exists below that width.

   WHY px AND NOT rem
   ---------------------------------------------------------------
   html{font-size} on this build is viewport-relative — 1rem == 1vw (3.9px @390).
   rem is FLUID here, not 16px. Chrome UI must not be fluid: a 44px tap target
   authored as 11.3rem would become 28px on a small phone and fail. Everything
   in this file is px, or clamp(px, vw, px) where fluidity is wanted.

   WHAT THIS ADDS
     1 · app bar        — fixed, glass-on-scroll, auto-hides downward
     2 · read progress  — the one gold element in the chrome (Law 1: gold marks
                          meaning; here it means "how far through the record")
     3 · section label  — the bar names the section you are standing in
     4 · drawer         — full-screen on phone, right sheet on tablet
     5 · back-to-top    — appears after two screens
     6 · ergonomics     — 44px minimums, safe-area, tap highlight, rhythm

   COLOUR comes from the .orox gold ramp so the chrome and the page are one
   material. Hairlines stay warm-neutral, never gold.
   ═════════════════════════════════════════════════════════════════════════════ */

:root {
  --orom-ink:        #080808;
  --orom-paper:      #F5F2EC;
  --orom-dim:        #A39D92;
  --orom-line:       rgb(245 242 236 / .10);
  --orom-line-hi:    rgb(245 242 236 / .20);
  --orom-gold:       #C9A46A;   /* gold-500 · primary accent */
  --orom-gold-hi:    #EAD795;   /* gold-200 · highlight      */
  --orom-gold-spec:  #FFF2A9;   /* gold-100 · specular       */
  --orom-bronze:     #8C6743;   /* gold-700 · numerals       */
  --orom-ease:       cubic-bezier(.19, 1, .22, 1);
  --orom-bar-h:      56px;
  --orom-safe-t:     env(safe-area-inset-top, 0px);
  --orom-safe-b:     env(safe-area-inset-bottom, 0px);
  --orom-safe-l:     env(safe-area-inset-left, 0px);
  --orom-safe-r:     env(safe-area-inset-right, 0px);
}

/* The chrome is inert above 1024px — desktop keeps the render it already has. */
.orom-bar,
.orom-drawer,
.orom-top { display: none; }


/* ─────────────────────────────────────────────────────────────────────────────
   TOUCH ERGONOMICS — keyed to the INPUT, not the viewport
   A 44px hit area is a finger measurement, so the right question is "is this a
   finger?", not "is this screen small?". Width gets it wrong at both ends:

     · an iPad Pro in landscape is 1366px. It fell outside the 1024px layer and
       got the desktop build — 24px footer links, aimed at with a thumb.
     · a 900px browser window on a laptop is inside 1024px and was getting
       finger-sized rows for a mouse that does not need them.

   `pointer: coarse` asks about the primary input device and answers both. It
   is also the honest reading of the numbers: 24px clears WCAG 2.5.8 (AA), so
   these links are not a defect for a mouse — they are a defect for a thumb.

   `min-height` does nothing to an inline box, so the row becomes inline-flex
   too. The visual size is unchanged; only the hit area grows.
   ───────────────────────────────────────────────────────────────────────────── */
@media (pointer: coarse) {
  .footer a,
  .orof__status-link,
  .app-button,
  .orox a:not([class*="btn"]):not([class*="cta"]) {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  /* the store badges are 32px artwork — the box grows, the badge does not */
  .app-button { justify-content: center; }
}

@media (max-width: 1024px) {

/* ─────────────────────────────────────────────────────────────────────────────
   0 · PAGE ERGONOMICS
   The things a touch build needs and a mouse build never asked for.
   ───────────────────────────────────────────────────────────────────────────── */
html {
  -webkit-text-size-adjust: 100%;   /* landscape rotation must not inflate type */
  -webkit-tap-highlight-color: transparent;
}
body { overflow-x: clip; }          /* decorative overhang clips, never scrolls */

/* Momentum scroll must not chain into the browser's own overscroll surface. */
html, body { overscroll-behavior-y: none; }

/* The legacy Webflow header carries a second logo. One logo per screen. */
.header { display: none; }

/* Anchor landings clear the fixed bar. */
:where(section[id], div[id]) { scroll-margin-top: calc(var(--orom-bar-h) + var(--orom-safe-t) + 12px); }

/* Touch ergonomics moved to a pointer query — see the block above the 1024px
   media query. Keeping them here as well would be a second source of truth. */

/* A pressed link should say so. Touch has no hover to fall back on. */
a, button, [role="button"] { -webkit-tap-highlight-color: transparent; }


/* ─────────────────────────────────────────────────────────────────────────────
   1 · APP BAR
   Transparent over the hero, glass once you have moved. It retreats on a
   downward scroll to give the reader back 56px, and returns the moment they
   scroll up — the standard mobile contract, and the only honest way to keep a
   persistent bar on a 35,000px page.
   ───────────────────────────────────────────────────────────────────────────── */
.orom-bar {
  position: fixed;
  inset: 0 0 auto;
  z-index: 4000;
  display: block;
  padding-top: var(--orom-safe-t);
  background: transparent;
  transform: translate3d(0, 0, 0);
  transition:
    transform .42s var(--orom-ease),
    background-color .3s ease,
    backdrop-filter .3s ease;
  will-change: transform;
}

/* materialised — the reader has left the hero */
.orom-bar[data-solid="1"] {
  background-color: rgb(8 8 8 / .72);
  -webkit-backdrop-filter: blur(18px) saturate(1.25);
          backdrop-filter: blur(18px) saturate(1.25);
}
.orom-bar[data-solid="1"]::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 1px;
  background: var(--orom-line);
}

/* retreated — scrolling down, and the drawer is shut */
.orom-bar[data-hidden="1"] { transform: translate3d(0, -100%, 0); }

.orom-bar__in {
  height: var(--orom-bar-h);
  display: flex;
  align-items: center;
  gap: 12px;
  padding-left: max(18px, var(--orom-safe-l));
  padding-right: max(12px, var(--orom-safe-r));
}

.orom-bar__logo {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 44px;
  /* 44 on BOTH axes. The mark is 26px tall and its aspect put the box at 43px
     wide — one pixel under, which is still a fail, and the only touch target
     left under the floor anywhere on the mobile build. */
  min-width: 44px;
  flex: 0 0 auto;
}
.orom-bar__logo img {
  height: 26px;
  width: auto;
  display: block;
}

/* ── the section you are standing in ─────────────────────────────────────────
   A long document should tell you where you are. The label cross-fades on
   change rather than cutting, so peripheral vision reads it as one object
   moving, not two objects swapping. */
.orom-bar__where {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  opacity: 0;
  transform: translateY(2px);
  transition: opacity .34s ease, transform .34s var(--orom-ease);
  pointer-events: none;
}
.orom-bar[data-solid="1"] .orom-bar__where { opacity: 1; transform: none; }
.orom-bar__where[data-swap="1"] { opacity: 0; transform: translateY(-2px); }

.orom-bar__dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--orom-gold);
  flex: 0 0 auto;
  box-shadow: 0 0 0 3px rgb(201 164 106 / .14);
}
.orom-bar__label {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--orom-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 359px) { .orom-bar__where { display: none; } }

/* ── read progress ───────────────────────────────────────────────────────────
   Sits on the bar's own hairline. Gold, because position in the record is
   meaning — this is the one place in the chrome the accent is earned. */
.orom-bar__progress {
  position: absolute;
  inset: auto 0 0;
  height: 1.5px;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--orom-bronze), var(--orom-gold) 45%, var(--orom-gold-spec));
  opacity: 0;
  transition: opacity .3s ease;
  will-change: transform;
}
.orom-bar[data-solid="1"] .orom-bar__progress { opacity: .95; }

/* ── menu button ─────────────────────────────────────────────────────────────
   Two rules, deliberately unequal — the short one on the right reads as a
   glyph rather than a hamburger clipart. They cross into an X on open. */
.orom-burger {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--orom-paper);
  border-radius: 12px;
  transition: background-color .22s ease;
}
.orom-burger:active { background-color: rgb(245 242 236 / .06); }
.orom-burger:focus-visible {
  outline: 1px solid var(--orom-gold);
  outline-offset: 2px;
}
.orom-burger__g {
  position: relative;
  width: 20px;
  height: 12px;
}
.orom-burger__g i {
  position: absolute;
  left: 0;
  height: 1.5px;
  background: currentColor;
  border-radius: 2px;
  transition: transform .44s var(--orom-ease), width .44s var(--orom-ease), opacity .2s ease;
}
.orom-burger__g i:nth-child(1) { top: 0;      width: 20px; }
.orom-burger__g i:nth-child(2) { bottom: 0;   width: 13px; }

.orom-burger[aria-expanded="true"] .orom-burger__g i:nth-child(1) {
  transform: translateY(5.25px) rotate(45deg);
}
.orom-burger[aria-expanded="true"] .orom-burger__g i:nth-child(2) {
  width: 20px;
  transform: translateY(-5.25px) rotate(-45deg);
}


/* ─────────────────────────────────────────────────────────────────────────────
   2 · DRAWER
   Phone: the whole screen, because a half-sheet on a 390px display is a
   compromise nobody asked for. Tablet: a right-hand sheet, because at 768px
   the page behind is still worth seeing.
   ───────────────────────────────────────────────────────────────────────────── */
.orom-drawer {
  position: fixed;
  inset: 0;
  /* Above the toast stack, not below it.
     The other lane's `.oroa-stack` is fixed at 4600 and was painting its
     install prompt straight over an OPEN modal drawer — covering the CTA and
     the last three rows. A transient notification must never occlude a modal
     the reader deliberately opened; the toast is not dismissed by this, it is
     simply behind, and is waiting when the menu closes.

     Ordering, deliberately spaced so a future layer can land between:
       3900 back-to-top · 4000 app bar · 4600 toasts (other lane) · 4700 drawer
     Still far below the 9999 preloader, which must beat everything. */
  z-index: 4700;
  display: block;
  visibility: hidden;
  pointer-events: none;
}
.orom-drawer[data-open="1"] { visibility: visible; pointer-events: auto; }

.orom-drawer__scrim {
  position: absolute;
  inset: 0;
  touch-action: none;          /* a drag on the scrim must not move the page */
  background: rgb(4 4 4 / .58);
  -webkit-backdrop-filter: blur(2px);
          backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity .38s ease;
}
.orom-drawer[data-open="1"] .orom-drawer__scrim { opacity: 1; }

.orom-drawer__panel {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: var(--orom-ink);
  opacity: 0;
  transform: scale(.988);
  transition: opacity .38s ease, transform .52s var(--orom-ease);
  overflow: hidden;
  isolation: isolate;
  touch-action: none;          /* only the body below is allowed to scroll */
}
.orom-drawer[data-open="1"] .orom-drawer__panel { opacity: 1; transform: none; }

/* the same ambient bloom the sections carry, so the drawer is the same room */
.orom-drawer__panel::before {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
  left: 50%;
  top: -34%;
  width: 150%;
  aspect-ratio: 2 / 1;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 50% 50%,
    rgba(201, 164, 106, .13) 0%,
    rgba(255, 242, 169, .04) 34%,
    transparent 68%);
}

/* head of the drawer — mirrors the bar exactly, so opening it moves nothing */
.orom-drawer__head {
  flex: 0 0 auto;
  height: var(--orom-bar-h);
  margin-top: var(--orom-safe-t);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-left: max(18px, var(--orom-safe-l));
  padding-right: max(12px, var(--orom-safe-r));

  /* The head carries its own opaque fill and its own layer.
     It sat transparent over the panel, which is fine on paper — the panel is
     opaque too — but the panel is a composited surface (isolation + a
     backdrop-filtered scrim beneath it), and a transparent child of a
     composited surface is where Chrome bleeds a stale tile through. A tablet
     capture showed the foot's legal row ghosting up here with nothing in the
     DOM to explain it. An opaque head with its own stacking context has no
     seam to bleed through, and it is what this element wants anyway: the list
     below scrolls, and a header a list scrolls under should never be see-through. */
  position: relative;
  z-index: 1;
  background: var(--orom-ink);
}
/* The mark is a link home; it needs a hand-sized box, not an image-sized one.
   Measured 43x26 before this — under the 44px floor on the short axis. */
.orom-drawer__head > a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  min-width: 44px;
}
.orom-drawer__head img { height: 26px; width: auto; display: block; }

.orom-drawer__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  touch-action: pan-y;
  /* T R B L — the right inset belongs on the right. The two were transposed,
     which is invisible in portrait (both insets are 0) and puts the list under
     the notch in landscape, where this layer still applies. */
  padding: 10px max(20px, var(--orom-safe-r)) 10px max(20px, var(--orom-safe-l));
  scrollbar-width: none;             /* the panel is the frame; a track inside
                                        it draws a second edge and reads as a
                                        seam. The list scrolls without one. */

  /* Thirteen rows do not fit a 812px phone and never will. What was wrong was
     not that the list scrolled — it was that the footer's gradient sat on top
     of it and sliced a row through the middle, which reads as a bug rather
     than as more content. The list now passes under its own edges instead:
     content dissolves at the head and the foot, which is the same cue a native
     list gives and needs no explanation. */
  -webkit-mask-image: linear-gradient(180deg,
    transparent 0, #000 12px, #000 calc(100% - 52px), transparent 100%);
          mask-image: linear-gradient(180deg,
    transparent 0, #000 12px, #000 calc(100% - 52px), transparent 100%);
}
.orom-drawer__body::-webkit-scrollbar { width: 0; height: 0; }
.orom-drawer__panel:focus { outline: none; }   /* silent focus host, see runtime */

/* ── group ───────────────────────────────────────────────────────────────────
   The heading is a partition, not a caption: a full-width hairline with the
   name sitting on it and — once oro-chapters.js is loaded — the chapter number
   at the opposite end. `display:flex` is declared here rather than only in
   oro-chapters.css so the heading has the same metrics whether or not that
   file is present. */
.orom-group + .orom-group { margin-top: 12px; }

.orom-group__label {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--orom-dim);
  padding: 0 8px 7px 12px;
  border-bottom: 1px solid var(--orom-line);
  margin-bottom: 4px;
}

/* Once oro-chapters.js is loaded the heading is not a caption — it is the
   control that opens its chapter. The chip sets its height at 36px, which is
   under the 44px floor this file enforces everywhere else. Growing the hit
   area with a pseudo-element buys the missing 8px without spending 8px of
   vertical space in a list that is already taller than the screen. */
.orom-group__label::after {
  content: "";
  position: absolute;
  inset: -6px 0;    /* 33.6px of type + 12 = 45.6px of target */
}

/* ── row ─────────────────────────────────────────────────────────────────────
   [glyph] [label] ·············· [index]

   Three columns on a grid so the labels of thirteen rows share one left edge
   no matter how wide the index gets. 44px is the floor Apple and Google both
   publish for a touch target; the row sits exactly on it, because the list has
   to fit a phone and every pixel above the floor is a row pushed off-screen.

   The active row changes three things and no more: a gold rule at the leading
   edge, a lit glyph, and a gold index. */
.orom-link {
  position: relative;
  display: grid;
  grid-template-columns: 26px 1fr auto;
  align-items: center;
  gap: 0 13px;
  min-height: 44px;
  padding: 3px 8px 3px 12px;
  border-radius: 10px;
  text-decoration: none;
  color: var(--orom-paper);
  transition: background-color .2s ease;
}
.orom-link::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 2px;
  height: 0;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--orom-gold-hi), var(--orom-gold));
  transform: translateY(-50%);
  transition: height .42s var(--orom-ease);
}
.orom-link:active { background-color: rgb(245 242 236 / .05); }
.orom-link:focus-visible {
  outline: 1px solid var(--orom-gold);
  outline-offset: 1px;
}

/* ── partition between rows ──────────────────────────────────────────────────
   Inset to the label's own left edge, so it separates without drawing a table.
   On the first row of a group the group rule above is already doing the job. */
.orom-link + .orom-link::after {
  content: "";
  position: absolute;
  left: 51px;              /* 12 padding + 26 glyph + 13 gap */
  right: 8px;
  top: 0;
  height: 1px;
  background: rgb(245 242 236 / .055);
}

/* ── the glyph ───────────────────────────────────────────────────────────────
   Borderless by default so thirteen of them do not read as thirteen buttons.
   The backplate belongs to the active row alone — gold marks meaning, and the
   only meaning here is "you are standing in this one". */
.orom-link__i {
  position: relative;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  color: rgb(245 242 236 / .40);
  transition: color .3s ease;
}
.orom-link__i svg { display: block; overflow: visible; }
.orom-link__i::before {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 9px;
  background:
    radial-gradient(circle at 50% 35%, rgb(201 164 106 / .22), rgb(201 164 106 / .05) 70%);
  border: 1px solid rgb(201 164 106 / .30);
  opacity: 0;
  transform: scale(.82);
  transition: opacity .32s ease, transform .46s var(--orom-ease);
}

.orom-link__t {
  font-size: 16.5px;
  font-weight: 500;
  letter-spacing: -.01em;
  line-height: 1.2;
  color: rgb(245 242 236 / .86);
  transition: color .3s ease;
}

/* The index reads as an index — a position in the record, not a label. */
.orom-link__n {
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: .1em;
  font-variant-numeric: tabular-nums;
  /* .26 is 2.09:1 — the row numerals were decoration nobody could read.
     .58 is 6.27:1 and keeps them subordinate to the label beside them. */
  color: rgb(245 242 236 / .58);
  transition: color .3s ease;
}

.orom-link[data-active="1"]::before { height: 22px; }
.orom-link[data-active="1"] .orom-link__i { color: var(--orom-gold-hi); }
.orom-link[data-active="1"] .orom-link__i::before { opacity: 1; transform: none; }
.orom-link[data-active="1"] .orom-link__n { color: var(--orom-gold-hi); }
.orom-link[data-active="1"] .orom-link__t { color: var(--orom-paper); }

/* ── foot: the action, then the legals ───────────────────────────────────── */
/* Solid, not a gradient. The gradient was translucent, so the list scrolled
   visibly underneath it and the topmost row was always half-erased. An opaque
   footer with a hairline is an edge; a translucent one is a smear. */
.orom-drawer__foot {
  flex: 0 0 auto;
  padding: 8px max(20px, var(--orom-safe-r))
           calc(8px + var(--orom-safe-b)) max(20px, var(--orom-safe-l));
  border-top: 1px solid var(--orom-line);
  background: var(--orom-ink);
}

.orom-cta {
  position: relative;
  overflow: hidden;                  /* clips the sheen to the pill */
  isolation: isolate;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 50px;
  padding: 0 20px;
  border-radius: 999px;
  text-decoration: none;
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--orom-ink);
  background: linear-gradient(180deg, var(--orom-gold-hi), var(--orom-gold));
  box-shadow: 0 1px 0 rgb(255 242 169 / .5) inset, 0 8px 24px rgb(201 164 106 / .18);
  transition: transform .2s var(--orom-ease), box-shadow .2s ease;
}
.orom-cta:active { transform: scale(.985); }
.orom-cta svg { flex: 0 0 auto; }

/* One pass of light across the gold, once, as the drawer settles. The site's
   whole subject is assay — metal read by how it takes light — so the single
   place the chrome is allowed to be theatrical is the one gold surface in it. */
.orom-cta__sheen {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transform: translateX(-130%);
  background: linear-gradient(105deg,
    transparent 34%, rgb(255 255 255 / .42) 50%, transparent 66%);
}
.orom-drawer[data-open="1"] .orom-cta__sheen {
  animation: orom-sheen 1.05s var(--orom-ease) calc(var(--orom-d, 0ms) + 200ms) 1 both;
}
@keyframes orom-sheen {
  from { transform: translateX(-130%); }
  to   { transform: translateX(130%); }
}

.orom-legal {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
  padding-left: 2px;
}
.orom-legal a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  font-size: 12.5px;
  color: var(--orom-dim);
  text-decoration: none;
}
.orom-legal a:active { color: var(--orom-paper); }
.orom-legal span { color: rgb(245 242 236 / .22); font-size: 12.5px; }

/* ── entrance ────────────────────────────────────────────────────────────────
   The delays themselves are assigned by oro-mobile.js (`restagger`), which is
   the only place that can know the final order once oro-chapters.js has
   prepended its group. What lives here is the shape of the movement.

   Not one interval for everything. A flat step across seventeen elements reads
   as a conveyor belt; a beat between groups and a tighter step inside them
   reads as the structure the menu actually has — which is the whole point of
   grouping it. */
.orom-drawer [data-stagger] {
  opacity: 0;
  transform: translateY(10px);
  /* the exit: no stagger, no ceremony — closing should feel decided */
  transition:
    opacity .18s ease,
    transform .22s var(--orom-ease);
}
.orom-drawer[data-open="1"] [data-stagger] {
  opacity: 1;
  transform: none;
  transition:
    opacity .44s ease var(--orom-d, 0ms),
    transform .56s var(--orom-ease) var(--orom-d, 0ms);
}

/* The glyph lands just behind its own row — a beat late, so the row arrives
   first and the mark settles into it. Rotation is small enough to register as
   weight rather than as a spin. */
.orom-drawer [data-stagger] .orom-link__i {
  opacity: 0;
  transform: scale(.78) rotate(-10deg);
  /* The exit. Without it `opacity` and `transform` are absent from the
     transition list on the way out, so every glyph snapped to invisible in one
     frame while its own row was still fading — a pop at the start of each
     close. It leaves on the row's schedule, not its own. */
  transition:
    opacity .16s ease,
    transform .22s var(--orom-ease),
    color .3s ease;
}
.orom-drawer[data-open="1"] [data-stagger] .orom-link__i {
  opacity: 1;
  transform: none;
  transition:
    opacity .34s ease calc(var(--orom-d, 0ms) + 80ms),
    transform .62s var(--orom-ease) calc(var(--orom-d, 0ms) + 80ms),
    color .3s ease;
}

/* ── tablet: a right sheet, not a takeover ───────────────────────────────── */
@media (min-width: 700px) {
  :root { --orom-bar-h: 64px; }

  .orom-bar__logo img,
  .orom-drawer__head img { height: 30px; }

  .orom-drawer__panel {
    inset: 0 0 0 auto;
    width: min(420px, 82vw);
    border-left: 1px solid var(--orom-line);
    box-shadow: -30px 0 80px rgb(0 0 0 / .5);
    transform: translateX(12px);
  }
  .orom-drawer__panel::before { top: -22%; width: 190%; }

  /* A 420px sheet on a tablet has height to spare, so the list stops fighting
     for it: rows breathe and the glyph column widens with them. */
  .orom-link            { min-height: 50px; grid-template-columns: 28px 1fr auto; gap: 0 14px; }
  .orom-link + .orom-link::after { left: 54px; }   /* 12 + 28 + 14 */
  .orom-link__i         { width: 28px; height: 28px; }
  .orom-link__t         { font-size: 17.5px; }
  .orom-group + .orom-group { margin-top: 16px; }
}


/* ─────────────────────────────────────────────────────────────────────────────
   3 · BACK TO TOP
   35,000px of page needs a way home that is not 40 swipes. Appears after two
   screens, steps aside for the drawer, and fades out over the footer so it
   never sits on top of the legal links.
   ───────────────────────────────────────────────────────────────────────────── */
.orom-top {
  position: fixed;
  z-index: 3900;
  right: max(16px, var(--orom-safe-r));
  bottom: calc(18px + var(--orom-safe-b));
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--orom-line-hi);
  background: rgb(12 12 12 / .72);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
          backdrop-filter: blur(14px) saturate(1.2);
  color: var(--orom-paper);
  cursor: pointer;
  padding: 0;
  opacity: 0;
  transform: translateY(10px) scale(.92);
  pointer-events: none;
  transition: opacity .34s ease, transform .44s var(--orom-ease);
}
.orom-top[data-show="1"] {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.orom-top:active { transform: scale(.94); }
.orom-top:focus-visible { outline: 1px solid var(--orom-gold); outline-offset: 3px; }


/* ─────────────────────────────────────────────────────────────────────────────
   4 · MOBILE RHYTHM
   The page was composed at 1440. At 390 the same vertical padding reads as
   hesitation. These pull the air back to a phone's proportions — nothing here
   changes what is on the page, only how much nothing sits between it.
   ───────────────────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  /* the scroll-scrub hero: 700vh is seven full swipes before the second
     section. Three is enough to read the move and still feel deliberate. */
  /* The hero scrub stays at its authored 700vh.
     Shortening it looked like free real estate — 700vh is seven swipes on a
     phone — but the hero and the benefits card-stack are one continuous
     Webflow IX2 choreography, and IX2 caches its scroll offsets at load rather
     than deriving them from the container. At 320vh the cards began rising at
     37%% of the hero instead of 50%%, so they arrived while the device was still
     on screen and ORO's copy rendered on top of the old template's chat mock-up.
     At 500vh they still collided at 55%%. Measured, not assumed.

     The length was never the real complaint anyway: the dead band above the
     device was, and that is fixed below. A reader who does not want the scrub
     now skips the whole chapter from the menu or the pager, which is the
     honest answer to a long hero. */

  .orox { padding-top: 56px; padding-bottom: 56px; }
  .orox-divider-sc { padding-top: 0; padding-bottom: 0; }

  /* ── hero stage: the device has to fill a phone-shaped stage ───────────────
     The gap between the copy and the device, and the dead band under it, are
     the same defect seen at two scroll positions: a 64vh device in an 844px
     viewport cannot fill it, so wherever you put the thing, the leftover has
     to go somewhere. Moving it only decides which end gets the hole —
     measured, at 64vh:

       top   entrance gap   clear of bar at rest   dead band below
       16vh      238px            −5px                 253px
       24vh      306px            62px                 186px
       31vh      365px           121px                 127px

     The sum barely moves. Size is the lever, not position. At 80vh the device
     is 333×675 on a 390px screen — 29px of margin each side, still framed, not
     bleeding — and the entrance gap falls to 194px while the resting position
     sits 28px under the bar with 84px beneath. Both ends are fixed at once.

     `height` is scoped to ≤479px deliberately. Above that the page's own GSAP
     scrub owns this property (`heroTargets` 140rem → 65vh, gated at
     `min-width: 480px` in index.html), and an !important here would freeze that
     animation mid-flight on every tablet. Tablets keep the authored height and
     take the position fix alone. */
  .hero-scale-block { top: 24vh; }

  @media (max-width: 479px) {
    .hero-scale-block {
      height: 80vh !important;   /* GSAP does not run at this width */
      top: 20vh;
    }
  }

}



  /* ── one screen in the phone, not two ───────────────────────────────
     The device stacks three screens and the page never turns the old one off,
     so two paint at once and the type of one shows through the other.

       .mobile    the Lottie (oro-phone-animation1-v4.json). Fully migrated by
                  the visuals lane — "Foundations wraps up today", "Module 4 of
                  6", "Verified on-chain", a gold outgoing bubble. This is the
                  one to show: it is on-brand AND it animates.
       .false-p   a still of oro-screen3.webp. Correct artwork, but redundant
                  the moment the animation is up, and it is the layer that was
                  bleeding through.

     index.html's `innerWidth <= 479` block switches `.mobile` on by writing an
     inline display:block from a setInterval. Keying off that same inline style
     means the still comes back by itself the instant that script hides the
     animation again — no second source of truth, and nothing to keep in sync.

     Opacity rather than display: a solid backing would square off the phone's
     rounded screen, and nothing in this subtree clips. */
  .hero-phone-screen.mobile[style*="display: block"] ~ .hero-phone-screen.false-p {
    opacity: 0;
  }


/* ─────────────────────────────────────────────────────────────────────────────
   4b · THE DRAWER, CHOREOGRAPHED
   The panel already arrived correctly; it arrived without character. This pass
   gives the open a direction and the list a sequence. Four ideas, no more —
   a menu that performs five tricks reads as a demo, not as navigation.

     1 · the panel unfolds FROM the button that opened it
     2 · the rules under each heading draw themselves
     3 · the row you are on carries a slow travelling light
     4 · the room breathes while you are in it

   Everything here is transform/opacity/clip-path only — compositor properties,
   no layout, no paint of the list itself. All of it is switched off wholesale
   by the reduced-motion block that follows.
   ───────────────────────────────────────────────────────────────────────────── */

/* ── 1 · unfold from the burger ──────────────────────────────────────────────
   The panel used to fade and scale from its own centre, which is the one place
   the reader was NOT looking — their finger was top-right, on the button. A
   circular clip opened from that corner ties cause to effect: the menu is not
   a new screen that appeared, it is this button, opened.

   140% radius so the far corner is reached before the ease flattens out;
   anything less and the last diagonal sliver pops in at the end. */
/* Authored as a one-shot ANIMATION, not a transition, and this is the whole
   point of the construction: a transition would mean the panel's resting state
   is `circle(0%)` — clipped to nothing — and it only becomes visible because a
   transition ran. Anything that stops transitions advancing then leaves the
   menu open, focus-trapped, and completely invisible. (Caught exactly that way:
   the preview pane pauses rAF, and the panel stayed at 0% forever.)

   With an animation the resting state is unclipped. If the animation runs the
   panel unfolds; if it never runs — paused rAF, an engine that ignores it, a
   dropped frame budget — the menu is simply there. The failure mode is "no
   animation", never "no menu". */
.orom-drawer__panel {
  transition:
    opacity .30s ease,
    transform .52s var(--orom-ease);
}
.orom-drawer[data-open="1"] .orom-drawer__panel {
  animation: orom-unfold .62s var(--orom-ease);
}
@keyframes orom-unfold {
  from { clip-path: circle(0% at calc(100% - 34px) 34px); }
  to   { clip-path: circle(142% at calc(100% - 34px) 34px); }
}

/* ── 2 · the rules draw ──────────────────────────────────────────────────────
   A heading's underline is a measurement of the group beneath it, so it is
   drawn rather than switched on. The border moves to a pseudo-element to be
   scaleable; the element keeps its box exactly. */
.orom-group__label { border-bottom-color: transparent !important; position: relative; }
.orom-group__label::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: var(--orom-line);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform .72s var(--orom-ease) var(--orom-d, 0ms);
}
.orom-drawer[data-open="1"] .orom-group__label::after { transform: scaleX(1); }

/* the chapter you are standing in gets a warm rule, not just a warm chip */
.orom-group[data-oroch-here="1"] .orom-group__label::after {
  background: linear-gradient(90deg, var(--orom-gold), transparent 70%);
}

/* ── 3 · light along the active row ──────────────────────────────────────────
   The active row already has a gold rule at its edge. This walks a soft
   highlight across it — slow, low-contrast, once every eight seconds. It reads
   as "live" in peripheral vision and is invisible if you look straight at it,
   which is the correct weight for an indicator that is not asking to be
   clicked. Only ever one element on screen runs it. */
.orom-link[data-active="1"] {
  background-image: linear-gradient(90deg,
    transparent 0%,
    rgb(201 164 106 / .085) 42%,
    rgb(255 242 169 / .13) 50%,
    rgb(201 164 106 / .085) 58%,
    transparent 100%);
  background-size: 220% 100%;
  background-repeat: no-repeat;
  animation: orom-row-sheen 8s var(--orom-ease) 1.2s infinite;
}
@keyframes orom-row-sheen {
  0%   { background-position: 190% 0; }
  38%  { background-position: -90% 0; }
  100% { background-position: -90% 0; }
}

/* ── 4 · the room breathes ───────────────────────────────────────────────────
   The bloom behind the list drifts a few pixels over half a minute. Far too
   slow to read as motion; enough that the panel is never quite a still image.
   Paused when shut so a closed drawer costs no frames. */
.orom-drawer[data-open="1"] .orom-drawer__panel::before {
  animation: orom-bloom-drift 34s ease-in-out infinite alternate;
}
@keyframes orom-bloom-drift {
  from { transform: translateX(-50%) translate3d(-3%, -1.5%, 0) scale(1); }
  to   { transform: translateX(-50%) translate3d(3%, 2%, 0) scale(1.07); }
}

/* ── the close glyph turns in ────────────────────────────────────────────────
   It is the same two rules as the burger, so it should arrive as those rules
   moving rather than as an X that was always there. */
.orom-drawer__head .orom-burger { transform: rotate(-45deg); opacity: 0; transition: transform .5s var(--orom-ease) .12s, opacity .3s ease .12s; }
.orom-drawer[data-open="1"] .orom-drawer__head .orom-burger { transform: none; opacity: 1; }

/* ── the numerals settle last ────────────────────────────────────────────────
   Label first, then its number. 90ms behind its own row, so the eye reads the
   word and the index confirms it, rather than both competing on arrival. */
.orom-drawer [data-stagger] .orom-link__n {
  opacity: 0;
  transform: translateX(-4px);
}
.orom-drawer[data-open="1"] [data-stagger] .orom-link__n {
  opacity: 1;
  transform: none;
  transition:
    opacity .42s ease calc(var(--orom-d, 0ms) + 90ms),
    transform .52s var(--orom-ease) calc(var(--orom-d, 0ms) + 90ms);
}

/* ── tablet: the sheet slides, so the unfold would fight it ──────────────────
   At ≥700px the panel is a right-hand sheet with its own translate. A circular
   clip on a sliding panel reads as two competing entrances, so the sheet keeps
   the slide and drops the unfold. */
@media (min-width: 700px) {
  .orom-drawer[data-open="1"] .orom-drawer__panel { animation: none; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   5 · REDUCED MOTION
   Everything above still works; it simply stops moving. The bar no longer
   retreats, because a bar that appears and disappears without transit is worse
   than one that stays.
   ───────────────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .orom-bar,
  .orom-drawer__panel,
  .orom-drawer__scrim,
  .orom-drawer [data-stagger],
  .orom-drawer [data-stagger] .orom-link__i,
  .orom-link::before,
  .orom-link__i::before,
  .orom-burger__g i,
  .orom-top {
    transition-duration: .01ms !important;
    transition-delay: 0ms !important;
  }
  .orom-bar[data-hidden="1"] { transform: none; }
  .orom-drawer [data-stagger] { opacity: 1; transform: none; }
  /* the glyph is content, not decoration — it must be there, just not arrive */
  .orom-drawer [data-stagger] .orom-link__i { opacity: 1; transform: none; }
  .orom-cta__sheen { display: none; }

  /* 4b, switched off wholesale. The clip must land OPEN, not at 0% — a panel
     stuck at circle(0%) is an invisible menu, which is worse than an abrupt
     one. Same for the numerals and the close glyph: they are content. */
  .orom-drawer[data-open="1"] .orom-drawer__panel { animation: none !important; }
  .orom-group__label::after { transform: scaleX(1) !important; transition: none !important; }
  .orom-link[data-active="1"] { animation: none !important; background-image: none !important; }
  .orom-drawer[data-open="1"] .orom-drawer__panel::before { animation: none !important; }
  .orom-drawer__head .orom-burger { transform: none !important; opacity: 1 !important; }
  .orom-drawer [data-stagger] .orom-link__n,
  .orom-drawer[data-open="1"] [data-stagger] .orom-link__n {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
}

/* Windows high-contrast: glass and gradients do not survive it, so give the
   chrome real borders instead of relying on luminance. */
@media (forced-colors: active) {
  .orom-bar[data-solid="1"] { border-bottom: 1px solid CanvasText; }
  .orom-drawer__panel { border: 1px solid CanvasText; }
  .orom-cta { border: 1px solid CanvasText; }
}

} /* end @media (max-width: 1024px) */
