/* =====================================================================
   Pluto — MOBILE LAYER (phones + tablets)   ·  Phase 1: Catalog
   ---------------------------------------------------------------------
   Additive stylesheet. Loaded AFTER css/style.css by app.html.
   Every rule is gated behind the mobile query
   `(max-width: 700px), (hover: none) and (pointer: coarse)` (plus, for
   JS-driven states, a `body.is-phone` / state class). The first clause
   catches narrow windows; the second catches any touch device with no
   hover-capable pointer (phones AND tablets — iPads, Android tablets),
   regardless of width. Laptops/desktops (hover + fine pointer) are never
   matched, even in a narrow window, so their rendering is unchanged.

   Design intent (agreed with Kyle):
     • Catalog + Cut are the touch-first modes; Design is desktop-only
       (blocked on phones AND tablets alike).
     • Catalog on touch = big 3D viewer up top + a swipe-up bottom sheet
       holding the Description and Cutting Sequence.
   All colors come from the existing theme variables so light/dark follow.
   ===================================================================== */

/* JS-injected controls are hidden by default; only the mobile query
   below reveals them (covers a touch→desktop resize). */
.mobile-hamburger { display: none; }
.mobile-collapse-caret { display: none; }
/* Transparent to layout off-phone, so the toggle group behaves like normal
   inline siblings on desktop; the phone breakpoint makes it a real row. */
.mobile-toggle-row { display: contents; }

@media (max-width: 700px), (hover: none) and (pointer: coarse) {

  /* ---- iOS Safari viewport: use small/dynamic vh so the URL bar doesn't
     crop the layout. Fall back to 100vh where svh is unsupported. ------- */
  html, body { overflow-x: hidden; }   /* safety net against 1-2px spills */
  .app {
    height: 100vh;      /* fallback */
    height: 100svh;
    /* No status-bar row on mobile — it's hidden below (desktop-only activity
       feed), so drop the trailing 22px track to reclaim the space. */
    grid-template-rows: 48px auto 1fr;
    /* Pin the single column to the viewport. Without this the implicit
       grid track sizes to MAX-content (ignoring flex-wrap), so the
       Catalog toolbar's unwrapped width blew the whole app past 390px. */
    grid-template-columns: minmax(0, 1fr);
    width: 100vw;
    max-width: 100vw;
    overflow-x: hidden;
  }
  /* Status bar is a desktop activity feed — hide it on mobile. */
  .status-bar { display: none; }
  /* Mode roots must fill — never exceed — that column. */
  #cutModeRoot, #cuttingModeRoot, #designModeRoot {
    min-width: 0;
    max-width: 100vw;
  }

  /* ================= HEADER ================= */
  .app-header {
    gap: 8px;
    padding: 0 8px;
    overflow: hidden;
  }
  /* Compact brand — logo only on phone (name/tag would crowd the pills). */
  .brand {
    padding-right: 6px;
    border-right: none;
    gap: 7px;
    flex-shrink: 0;
  }
  .brand img { width: 26px; height: 26px; }
  .brand-name { display: none; }

  /* Mode pills: pull them out of absolute-centering and let them sit in
     the flex row so they never collide with the brand / hamburger. */
  .mode-pill-toggle {
    position: static;
    left: auto; top: auto;
    transform: none;
    margin: 0 auto;
    padding: 2px;
  }
  .mode-pill { padding: 6px 11px; font-size: 11.5px; }
  .mode-pill-lg { padding: 6px 13px; }

  /* Design pill is desktop-only on phone. Show a single indicator per
     state: when logged out the app already renders a 🔒 lock, so only add
     our 🖥 monitor when the pill is NOT locked (avoids a double icon). */
  body.is-phone .mode-pill[data-mode="design"],
  body.is-phone .mode-pill[data-mode="render"] {
    opacity: 0.45;
  }
  body.is-phone .mode-pill[data-mode="render"]::after,
  body.is-phone .mode-pill[data-mode="design"]:not(.locked)::after {
    content: "🖥";
    font-size: 9px;
    margin-left: 4px;
    vertical-align: middle;
  }

  /* Auth: hide the wide "Log in / Register" text button; the avatar beside
     it already prompts login when logged out, so it covers both cases. */
  .header-user { gap: 6px; flex-shrink: 0; }
  #btnAuth.header-auth { display: none; }

  /* Menu bar collapses behind a hamburger (button injected by JS). */
  .menu-bar { display: none; }
  .app-header .mobile-hamburger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px; height: 34px;
    flex-shrink: 0;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    background: var(--bg-3);
    color: var(--text-0);
    font-size: 17px;
    cursor: pointer;
  }
  /* Expanded menu — a vertical sheet dropping from the header. */
  body.menu-open .menu-bar {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    position: fixed;
    top: 48px; left: 0; right: 0;
    z-index: 60;
    background: var(--bg-1);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-2);
    padding: 6px;
    gap: 2px;
    max-height: calc(100svh - 48px);
    overflow-y: auto;
  }
  body.menu-open .menu-root { width: 100%; }
  body.menu-open .menu-root > .menu-btn {
    width: 100%;
    text-align: left;
    padding: 12px 14px;
    font-size: 14px;
  }
  /* Nested dropdowns render inline (accordion) rather than floating. */
  body.menu-open .menu-dropdown {
    position: static !important;
    display: none;
    box-shadow: none;
    border: none;
    background: var(--bg-2);
    border-radius: var(--radius-sm);
    margin: 2px 0 4px;
  }
  body.menu-open .menu-root.open > .menu-dropdown { display: block; }
  body.menu-open .menu-item { padding: 11px 16px; font-size: 13px; }
  body.menu-open .menu-item .kbd { display: none; }

  /* Phone: strip the hamburger to only what a touch user can act on.
     File / Edit / View all operate on the Design-mode workbench, and Design
     editing is desktop-only on phone — so every item in them is either a
     greyed-out no-op or a separately-hidden desktop feature. Drop the whole
     menus. Keyboard Shortcuts is dead weight with no keyboard. What remains:
     Tools (self-contained reference modals) and Help (User Manual + About). */
  body.menu-open .menu-root[data-menu="file"],
  body.menu-open .menu-root[data-menu="edit"],
  body.menu-open .menu-root[data-menu="view"],
  body.menu-open .menu-item[data-action="help-shortcuts"] {
    display: none;
  }

  /* Scrim behind the open menu */
  body.menu-open::before {
    content: "";
    position: fixed;
    inset: 48px 0 0 0;
    background: rgba(0,0,0,0.45);
    z-index: 55;
  }
  /* The menu bar (z-index 60) lives inside .app-header, which is its own
     stacking context at z-index 40 — below the z-55 scrim. That trapped the
     whole accordion under the scrim, so taps hit the scrim instead of the
     menu (Tools/Help looked dead). Lift the header above the scrim while the
     menu is open so its items are tappable; the scrim still dims the content
     below. */
  body.menu-open .app-header { z-index: 60; }

  /* Design mode is desktop-only on phones, so the profile card's "Design"
     open button (which would jump into Design mode) is hidden here. The
     openInMode()/setAppMode() guards are the behavioral backstop. */
  .profile-card-actions .profile-open[data-mode="design"] { display: none; }

  /* ================= Tools modals: mobile readability =================
     The reference charts are wide multi-column grids (1000–1200px) that
     cram unreadably at phone width. Give them near-full-screen size,
     un-squish the toolbars, and reflow the text tables into stacked,
     labelled cards. */
  .modal.ri-chart-modal,
  .modal.gemdb-modal {
    width: 96vw;
    max-width: 96vw;
    height: 90vh;
    max-height: 90vh;
  }

  /* Toolbar: search gets its own row so the sort buttons + count have room
     (they were squished together next to the search box). */
  .ri-toolbar,
  .gemdb-toolbar {
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 12px;
  }
  .ri-toolbar .ri-search,
  .gemdb-toolbar .ri-search { flex: 1 1 100%; }
  .ri-sort-btn { padding: 9px 16px; font-size: 12px; }
  .ri-count { margin-left: auto; }

  /* Text charts (pleochroism, cleavage, heat, lap) — one tap-to-expand row
     per material. Collapsed shows just the name + a chevron; tapping the row
     (see the .lap-open toggle in app.html) reveals the labelled fields. The
     cramped multi-column grid is gone. */
  .modal.ri-chart-modal .lap-colhead { display: none; }
  .modal.ri-chart-modal .lap-row {
    display: block;
    position: relative;
    padding: 13px 34px 13px 16px; /* right pad leaves room for the chevron */
    cursor: pointer;
  }
  .modal.ri-chart-modal .lap-row::after {
    content: "▸";
    position: absolute;
    right: 15px;
    top: 13px;
    color: var(--text-3);
    font-size: 11px;
  }
  .modal.ri-chart-modal .lap-row.lap-open::after { content: "▾"; }
  .modal.ri-chart-modal .lap-row .ri-col-name {
    display: block;
    font-size: 14px;
  }
  /* Fields are hidden until the row is expanded. */
  .modal.ri-chart-modal .lap-row > span:not(.ri-col-name) { display: none; }
  .modal.ri-chart-modal .lap-row.lap-open > span:not(.ri-col-name) {
    display: block;
    margin-top: 4px;
  }
  .modal.ri-chart-modal .lap-row.lap-open .ri-col-name { margin-bottom: 6px; }
  .modal.ri-chart-modal .lap-row > span:not(.ri-col-name)::before {
    color: var(--text-3);
    font-weight: 700;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.4px;
  }
  /* Per-chart field labels — nth-child order matches each table's columns. */
  .pleo-guide-modal .lap-row > span:nth-child(2)::before { content: "Optic — "; }
  .pleo-guide-modal .lap-row > span:nth-child(3)::before { content: "Pleochroism — "; }
  .pleo-guide-modal .lap-row > span:nth-child(4)::before { content: "Axis colors — "; }
  .pleo-guide-modal .lap-row > span:nth-child(5)::before { content: "Orientation — "; }
  .cleave-guide-modal .lap-row > span:nth-child(2)::before { content: "Cleavage — "; }
  .cleave-guide-modal .lap-row > span:nth-child(3)::before { content: "Toughness — "; }
  .cleave-guide-modal .lap-row > span:nth-child(4)::before { content: "Handling — "; }
  .heat-guide-modal .lap-row > span:nth-child(2)::before { content: "Heat — "; }
  .heat-guide-modal .lap-row > span:nth-child(3)::before { content: "Chemicals — "; }
  .heat-guide-modal .lap-row > span:nth-child(4)::before { content: "Ultrasonic — "; }
  .heat-guide-modal .lap-row > span:nth-child(5)::before { content: "Bench note — "; }
  .lap-guide-modal .lap-row > span:nth-child(2)::before { content: "Mohs — "; }
  .lap-guide-modal .lap-row > span:nth-child(3)::before { content: "Prepolish — "; }
  .lap-guide-modal .lap-row > span:nth-child(4)::before { content: "Polish — "; }
  .lap-guide-modal .lap-row > span:nth-child(5)::before { content: "Lap — "; }
  .lap-guide-modal .lap-row > span:nth-child(6)::before { content: "Notes — "; }

  /* Gem Reference Database — a compact dropdown picker replaces the gem-name
     list on phones (that list ate most of the screen). The detail panel then
     gets the whole modal to itself. */
  .gemdb-mobile-bar {
    display: block;
    padding: 10px 12px;
    border-bottom: 1px solid var(--border-soft);
  }
  .gemdb-select {
    width: 100%;
    padding: 10px;
    font-size: 14px;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    background: var(--bg-2);
    color: var(--text-0);
  }
  .gemdb-list-col { display: none; }
  .gemdb-detail { min-height: 0; padding: 16px; }
  .gemdb-cards { grid-template-columns: repeat(2, 1fr); }

  /* ================= CATALOG MODE (#cutModeRoot) ================= */
  #cutModeRoot.cut-mode-root {
    padding: 8px 8px 0;
    gap: 8px;
    /* viewer(flex) + fixed bottom sheet live here; root itself won't scroll */
    overflow: hidden;
    position: relative;   /* anchor for the absolutely-placed #mobileSheet */
  }
  /* Lift the canvas's floating bottom controls above the peeking sheet. */
  #cutModeRoot .view-toolbar { bottom: 80px; }
  /* Hide the click-to-spin axis gizmo on phone: it sat bottom-left and
     collided with the Markers / Facet# / X-Ray chips, and touch swipe-to-
     rotate already covers what it does. */
  #cutModeRoot .axis-gizmo { display: none; }

  /* Req 1: the per-window maximize (⤢) buttons don't work in the mobile
     layout — remove them in both Catalog and Cut. */
  #cutModeRoot [data-catalog-maximize],
  #cuttingModeRoot [data-cutting-maximize] { display: none; }

  /* Scope analysis tools aren't needed on phone (Studio / Hearts & Arrows /
     Hall of Mirrors / IdealScope / ASET) — hide just those. KEEP the
     Spotlights control (Kyle). !important beats the inline display the app
     sets in Render mode. */
  #cutModeRoot #scopeBtn,
  #cutModeRoot #scopeMenu,
  #cutModeRoot #scopeLegend,
  #cutModeRoot #scopeAperture { display: none !important; }
  /* Drop the render-controls cluster below the Crown/Pavilion/Girdle/Motion
     row so the Spotlights button no longer sits on top of Motion. */
  #cutModeRoot #scopeWrap { top: 54px; }

  /* Bottom-left toolbar: Markers / Facet # / X-Ray in a row, with Export on
     its own line above them (left-aligned). The toggles are grouped into a
     .mobile-toggle-row (by mobile-layer.js) so the left group stays narrow
     and never resizes the index/facet readout on the right. */
  #cutModeRoot .view-toolbar > .view-chip-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
  #cutModeRoot .view-toolbar > .view-chip-row .cut-export-wrap { order: -1; }
  #cutModeRoot .view-toolbar .mobile-toggle-row {
    display: flex;
    flex-direction: row;
    gap: 5px;
    flex-wrap: wrap;
  }
  /* Compact these three so Markers / Facet # / X-Ray all fit on one row. */
  #cutModeRoot .view-toolbar .mobile-toggle-row .view-chip { padding: 8px 9px; }

  /* ---- Toolbar: stack full-width, hide the desktop-only actions ---- */
  #cutModeRoot .cut-toolbar {
    gap: 8px 10px;
    padding: 8px 10px;
    min-height: 0;
    row-gap: 8px;
  }
  #cutModeRoot .cut-select-wrap {
    flex: 1 1 100%;
    gap: 8px;
  }
  #cutModeRoot .cut-select-wrap .field-label { display: none; }
  #cutModeRoot .design-browse-btn {
    width: 100%;
    flex: 1;
    padding: 10px 12px;
    font-size: 13px;
  }
  #cutModeRoot .cut-material-btn {
    flex: 1 1 100%;
    min-height: 40px;
  }
  /* "Open in Design" is desktop-only; Print is available from the menu. */
  #cutModeRoot #cutOpenInDesignBtn,
  #cutModeRoot #cutPrintBtn { display: none; }
  #cutModeRoot #cutOpenInCutBtn {
    flex: 1 1 100%;
    min-height: 40px;
    justify-content: center;
  }

  /* ---- Layout: single column; viewer first & tall, panels into sheet ---- */
  #cutModeRoot .cut-layout {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    flex: 1;
    min-height: 0;
    gap: 0;
  }
  /* The 3D viewer fills the remaining space above the sheet. */
  #cutModeRoot .cut-wire-col {
    order: 0;
    flex: 1;
    min-height: 0;
    overflow: hidden;
  }
  #cutModeRoot .cut-wire-col .pane { height: 100%; }

  /* Let every flex item shrink below its content width (default is
     min-width:auto, which was forcing the viewer pane to ~525px and
     overflowing the page). */
  #cutModeRoot .cut-layout,
  #cutModeRoot .cut-col,
  #cutModeRoot .pane,
  #cutModeRoot .pane-head,
  #cutModeRoot .pane-body {
    min-width: 0;
    max-width: 100%;
  }

  /* Bigger touch targets on the view chips floating over the canvas */
  #cutModeRoot .pane-chip,
  #cutModeRoot .view-chip {
    padding: 8px 12px;
    font-size: 12px;
  }
  /* Header + chip row must wrap so they never dictate a wide min-width. */
  #cutModeRoot .pane-head { flex-wrap: wrap; }
  #cutModeRoot .pane-chip-row {
    gap: 6px;
    row-gap: 6px;
    flex-wrap: wrap;
    min-width: 0;
  }

  /* ================= BOTTOM SHEET (built by mobile-layer.js) =========
     #mobileSheet is appended to #cutModeRoot and holds the breakdown +
     steps columns. Two snap states via body classes: peek / expanded. */
  #mobileSheet {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 30;
    background: var(--bg-1);
    border-top: 1px solid var(--border);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    box-shadow: 0 -8px 30px rgba(0,0,0,0.5);
    display: flex;
    flex-direction: column;
    height: 86svh;                                /* fixed; slides up/down */
    transform: translateY(calc(86svh - 72px));    /* peek: handle + title only */
    transition: transform 0.28s cubic-bezier(0.4,0,0.2,1);
    touch-action: none;
    will-change: transform;
  }
  body.sheet-expanded #mobileSheet {
    transform: translateY(0);
  }
  /* while dragging, JS drives transform inline — kill the transition */
  body.sheet-dragging #mobileSheet { transition: none; }

  .mobile-sheet-handle {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 8px 12px 6px;
    cursor: grab;
  }
  .mobile-sheet-grip {
    width: 40px; height: 4px;
    border-radius: 2px;
    background: var(--text-3);
  }
  .mobile-sheet-titlebar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    gap: 10px;
  }
  .mobile-sheet-title {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--text-2);
  }
  .mobile-sheet-caret {
    font-size: 12px;
    color: var(--text-3);
    transition: transform 0.28s ease;
  }
  body.sheet-expanded .mobile-sheet-caret { transform: rotate(180deg); }

  .mobile-sheet-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 0 4px 16px;
  }
  /* Panels sit naturally inside the sheet (no fixed 100% height / borders) */
  #mobileSheet .cut-col {
    overflow: visible;
    margin-bottom: 10px;
  }
  #mobileSheet .cut-col .pane {
    height: auto !important;
    border: none;
    background: transparent;
  }
  #mobileSheet .pane-body { overflow: visible; }
  #mobileSheet .cut-breakdown-body,
  #mobileSheet .cut-steps-list { height: auto; }
  /* Per-pane maximize buttons make no sense inside the sheet */
  #mobileSheet [data-catalog-maximize] { display: none; }

  /* ================= CUT MODE — bench companion (#cuttingModeRoot) =====
     Phone Cut mode is a "follow along at the machine" flow: your rough
     stone as it's being cut up top, the current step blown up big below,
     and a fixed bottom bar with large Prev / Next + keep-screen-on. */
  #cuttingModeRoot.cut-mode-root {
    padding: 8px 8px 0;
    gap: 8px;
    position: relative;
    overflow: hidden;
    padding-bottom: 66px;          /* clear the fixed bottom nav bar */
  }

  /* Toolbar: same full-width stacking as Catalog. */
  #cuttingModeRoot .cut-toolbar {
    gap: 8px 10px;
    padding: 8px 10px;
    min-height: 0;
    row-gap: 8px;
  }
  #cuttingModeRoot .cut-select-wrap { flex: 1 1 100%; gap: 8px; }
  #cuttingModeRoot .cut-select-wrap .field-label { display: none; }
  #cuttingModeRoot .design-browse-btn { width: 100%; flex: 1; padding: 10px 12px; font-size: 13px; }
  #cuttingModeRoot .cut-material-btn { flex: 1 1 100%; min-height: 40px; }

  /* Layout: single column. Show only the ROUGH stone (your progress);
     the target-design and machine panes are redundant on a phone — the
     step card below carries the angle + index numbers. */
  #cuttingModeRoot .cutting-layout {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    flex: none;
    gap: 0;
    min-width: 0;
  }
  /* Target-design viewer is hidden on phone; Rough + Machine are shown as
     collapsible windows (Rough collapsed by default, Machine expanded). */
  #cuttingModeRoot .cutting-col-design { display: none; }
  #cuttingModeRoot .cutting-col-rough {
    order: 0;
    flex: none;
    height: 32svh;
    min-height: 0;
    overflow: hidden;
  }
  #cuttingModeRoot .cutting-col-machine {
    order: 1;
    flex: none;
    height: 26svh;
    min-height: 0;
    overflow: hidden;
  }
  #cuttingModeRoot .cutting-col-rough .pane,
  #cuttingModeRoot .cutting-col-machine .pane { height: 100%; }
  #cuttingModeRoot .cutting-machine-body { min-width: 0; }
  #cuttingModeRoot .axis-gizmo { display: none; }
  /* Markers are available in the rough window, keeping the C / P / L / W …
     dimension LETTER but hiding the numeric VALUE (the rough size can't be
     set on phone). Only the value span is hidden; the letter stays. */
  #cuttingModeRoot .marker-value { display: none; }

  /* Collapsible windows (toggles injected by mobile-layer.js). */
  #cuttingModeRoot .cut-col.mobile-collapsed { height: auto; }
  #cuttingModeRoot .cut-col.mobile-collapsed .pane-body { display: none; }
  .mobile-collapsible-head { cursor: pointer; }
  /* Left-align the window titles (caret + title) and push the chip row to
     the right — otherwise space-between centred "Machine setup" (its chip
     row is just an invisible spacer) out of line with "Rough stone". */
  #cuttingModeRoot .mobile-collapsible-head { justify-content: flex-start; }
  #cuttingModeRoot .mobile-collapsible-head .pane-chip-row { margin-left: auto; }
  .mobile-collapse-caret {
    display: inline-block;
    font-size: 12px;
    color: var(--text-3);
    margin-right: 6px;
    transition: transform 0.2s ease;
    flex-shrink: 0;
  }
  .cut-col.mobile-collapsed .mobile-collapse-caret { transform: rotate(-90deg); }
  /* The rough L/W/D size inputs are set-once planning controls that floated
     over — and swamped — the small phone preview. Hide them so the preview
     stays a clean "watch your stone take shape" view (defaults to a cube). */
  #cuttingModeRoot .rough-controls { display: none; }
  #cuttingModeRoot #roughDimPanel, #cuttingModeRoot #roughMeasureToggle { display: none !important; }

  /* Let the panes shrink below content width (avoid the flex overflow). */
  #cuttingModeRoot .cutting-layout,
  #cuttingModeRoot .cut-col,
  #cuttingModeRoot .pane,
  #cuttingModeRoot .pane-head,
  #cuttingModeRoot .pane-body { min-width: 0; max-width: 100%; }
  #cuttingModeRoot .pane-head { flex-wrap: wrap; }
  #cuttingModeRoot .pane-chip-row { flex-wrap: wrap; gap: 6px; min-width: 0; }
  #cuttingModeRoot .pane-chip,
  #cuttingModeRoot .view-chip { padding: 7px 11px; font-size: 12px; }

  /* Instructions pane fills the rest and scrolls. */
  #cuttingModeRoot .cutting-instructions-pane {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  /* Compact the pane's inline step-nav header — the big controls live in
     the fixed bottom bar, so here we just keep the Cut-order chips. */
  #cuttingModeRoot .cutting-step-nav { flex-wrap: wrap; gap: 6px; row-gap: 6px; }
  #cuttingModeRoot .cutting-step-nav .cutting-step-counter,
  #cuttingModeRoot .cutting-step-nav #cuttingStepPrev,
  #cuttingModeRoot .cutting-step-nav #cuttingStepNext,
  #cuttingModeRoot .cutting-step-nav [data-cutting-maximize] { display: none; }
  /* Collapse each chip PAIR to a single toggle button: show only the active
     option and drop the "Cut order" / "Steps" labels (the button text says it
     all). Tapping the visible chip flips to the other — see mobile-layer.js. */
  #cuttingModeRoot .cutting-step-nav .cutting-order-label { display: none; }
  #cuttingModeRoot .cutting-step-nav .pane-chip-row .pane-chip:not(.active) { display: none; }

  /* Blow up the CURRENT step for at-the-bench legibility; dim the rest. */
  #cuttingModeRoot .cutting-steps-list { padding: 10px 10px 20px; }
  #cuttingModeRoot .cutting-steps-list .cut-step-item { padding: 10px 12px; }
  #cuttingModeRoot .cutting-steps-list .cut-step-item.current {
    padding: 14px 14px;
    border-radius: var(--radius-md);
  }
  #cuttingModeRoot .cutting-steps-list .cut-step-item.current .cs-head {
    font-size: 15px;
    flex-wrap: wrap;
    gap: 4px 12px;
  }
  #cuttingModeRoot .cutting-steps-list .cut-step-item.current .cs-name {
    font-size: 22px;
    letter-spacing: 0.5px;
  }
  #cuttingModeRoot .cutting-steps-list .cut-step-item.current .cs-instr {
    font-size: 14px;
    line-height: 1.5;
    margin-top: 6px;
  }
  #cuttingModeRoot .cutting-steps-list .cut-step-item.current .cs-idx {
    /* Tracks the desktop bump to 12px base — the current step's index list sits
       just under its instruction text (14px) in the hierarchy. */
    font-size: 14px;
    line-height: 1.5;
    margin-top: 6px;
  }

  /* ---- Fixed bottom step-nav bar (built by mobile-layer.js) ---- */
  .mobile-cut-nav {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 45;
    display: flex;
    align-items: stretch;
    gap: 6px;
    padding: 8px 8px calc(8px + env(safe-area-inset-bottom, 0px));
    background: var(--bg-1);
    border-top: 1px solid var(--border);
    box-shadow: 0 -6px 24px rgba(0,0,0,0.45);
  }
  .mcn-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 48px;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-md);
    background: var(--bg-3);
    color: var(--text-0);
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
    touch-action: manipulation;
  }
  .mcn-btn:active { transform: translateY(1px); }
  .mcn-next {
    flex: 1.3;
    background: linear-gradient(180deg, var(--gold), #cf9f52);
    color: #221a0c;
    border-color: transparent;
  }
  .mcn-btn:disabled { opacity: 0.4; }
  .mcn-center {
    flex: 1.1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 0;
  }
  .mcn-counter {
    font-size: 12px;
    font-weight: 700;
    color: var(--text-1);
    font-variant-numeric: tabular-nums;
    text-align: center;
    line-height: 1.15;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
  }
  .mcn-wake {
    font-size: 10px;
    letter-spacing: 0.3px;
    color: var(--text-3);
    border: 1px solid var(--border-soft);
    border-radius: 999px;
    padding: 3px 9px;
    background: var(--bg-2);
    cursor: pointer;
    white-space: nowrap;
  }
  .mcn-wake.on {
    color: #221a0c;
    background: var(--gold);
    border-color: transparent;
  }

  /* ================= FACETING DESIGN SELECTOR MODAL ================
     On phone the desktop modal (fixed 280px filter sidebar + results) was
     wider than the viewport, which forced the browser to zoom the whole
     page out. Go full-screen + single column, and collapse the big filter
     panel behind a toggle so the results list is what you see first. */
  .modal.design-selector-modal {
    width: 100vw;
    max-width: 100vw;
    height: 100svh;
    height: 100vh;                 /* fallback */
    height: 100svh;
    max-height: 100svh;
    border-radius: 0;
    border: none;
  }
  .design-selector-modal .design-selector-body {
    display: flex;
    flex-direction: column;
    gap: 0;
  }
  /* Filters hidden until toggled (button injected by mobile-layer.js). */
  .design-selector-modal .design-filter-panel {
    display: none;
    border-right: none;
    border-bottom: 1px solid var(--border-soft);
    max-height: 55svh;
    padding: 14px 16px;
  }
  .design-selector-modal.filters-open .design-filter-panel { display: flex; }
  .design-selector-modal .design-results-panel {
    flex: 1;
    min-height: 0;
    padding: 10px 12px 12px;
  }
  .design-selector-modal .design-results-list { gap: 8px; }
  /* Stack each row: name/meta full-width on top, thumbnails + stats below,
     so names get the whole row instead of being squeezed to "Illusio…". */
  .design-selector-modal .design-row {
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 8px 10px;
    padding: 12px;
  }
  .design-selector-modal .design-row-main { flex: 1 1 100%; order: 0; }
  .design-selector-modal .design-row-name { white-space: normal; }
  .design-selector-modal .design-row-thumbs { order: 1; }
  .design-selector-modal .design-row-stats { order: 2; margin-left: auto; }
  .design-selector-modal .design-thumb-img { width: 64px; height: 64px; }
  .df-filters-toggle {
    flex-shrink: 0;
    border: 1px solid var(--border-soft);
    background: var(--bg-2);
    color: var(--text-1);
    font-size: 12px;
    font-weight: 600;
    padding: 6px 12px;
    border-radius: 999px;
    cursor: pointer;
    touch-action: manipulation;
  }
  .df-filters-toggle.on {
    background: var(--gold);
    color: #221a0c;
    border-color: transparent;
  }

  /* ================= Touch niceties ================= */
  input[type="range"] { height: 28px; }
  .btn, .view-chip, .pane-chip, .menu-btn { touch-action: manipulation; }
  /* 16px text fields stop iOS Safari from auto-zooming the page (and never
     zooming back) when a field like the design search box is focused. This
     was what made the selector modal look "too large" after a tap. */
  input[type="text"],
  input[type="number"],
  input[type="search"],
  input[type="email"],
  input[type="password"],
  select,
  textarea { font-size: 16px; }
}

/* Extra-narrow phones */
@media (max-width: 380px) {
  .mode-pill { padding: 6px 9px; font-size: 11px; }
  .brand-name { font-size: 12px; }
}

/* Toast — created by mobile-layer.js; only ever shown on phone. */
.mobile-toast {
  position: fixed;
  left: 50%;
  bottom: 88px;
  transform: translate(-50%, 12px);
  max-width: 84vw;
  z-index: 200;
  background: var(--bg-4);
  color: var(--text-0);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
  padding: 11px 16px;
  font-size: 13px;
  line-height: 1.35;
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s ease, transform 0.22s ease;
}
.mobile-toast.show {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* =====================================================================
   v2.61: Reference bar-charts + User Manual — small-screen readability
   ---------------------------------------------------------------------
   Five Tools charts draw a scale bar per gemstone on a shared grid
   (--ri-cols): Refractive Index, Specific Gravity, Hardness (Mohs),
   Dispersion (Fire) and RI + DI. Their grids need ~480–520px of column
   minimums before the axis gets a single pixel, so on a phone the axis
   collapsed to nothing and the numeric columns overlapped — the charts
   were unreadable. The User Manual had the same problem for a different
   reason: a fixed 210px sidebar table of contents eating half the width.

   Gated on `max-width: 700px` ONLY — deliberately narrower than the rest
   of this file's `(hover:none) and (pointer:coarse)` condition. A portrait
   tablet (768px) shows the modal at 96vw ≈ 737px, which clears the grid's
   ~482px minimum with room for the axis, so tablets keep the real chart.
   Phones (and any window under 700px) get the stacked layout below.

   NOTE: `.ri-row` / `.ri-colhead` exist ONLY in these five bar charts. The
   text charts (Pleochroism / Cleavage & Toughness / Heat & Chemical / Lap
   & Polish) share the .ri-chart-modal shell but build rows from .lap-row,
   and already have their own tap-to-expand treatment earlier in this file.
   Nothing here touches them.
   ===================================================================== */
@media (max-width: 700px) {

  /* ---- Shell: use the screen. (The 96vw/90vh rule earlier in this file
     already covers .ri-chart-modal; the manual needs its own.) -------- */
  .modal.manual-modal {
    width: 96vw;
    max-width: 96vw;
    height: 92vh;
    max-height: 92vh;
  }

  /* ================= Bar charts: axis header ==================
     The header is a sibling ABOVE the scrolling row list, so it stays put
     while the list scrolls — it becomes the chart's permanent scale strip.
     Drop the "Gemstone" and numeric column captions (the per-row labels
     below carry that information now) and let the tick axis run the full
     width, on the same 14px side padding as the rows so every tick stays
     in register with every bar. */
  .modal.ri-chart-modal .ri-colhead {
    display: block;
    padding: 8px 14px 18px;   /* bottom pad = room for tick labels */
  }
  .modal.ri-chart-modal .ri-colhead > .ri-col-name,
  .modal.ri-chart-modal .ri-colhead > .ri-col-num { display: none; }
  .modal.ri-chart-modal .ri-colhead > .ri-col-axis { display: block; }
  /* The combined chart's axis is a sized box (16px relative / 40px true
     scale) with ticks inside it, so it needs far less bottom padding. */
  .modal.ri-chart-modal.combo-chart-modal .ri-colhead { padding-bottom: 6px; }

  /* ================= Bar charts: rows as stacked cards ==================
     Name → full-width scale bar → the numbers as labelled inline chips.
     Everything stays visible; no tap needed. */
  .modal.ri-chart-modal .ri-row {
    display: block;
    padding: 11px 14px 12px;
    min-height: 0;
    border-bottom: 1px solid var(--border-soft);
  }
  .modal.ri-chart-modal .ri-row:hover { background: none; }
  .modal.ri-chart-modal .ri-row .ri-col-name {
    display: block;
    white-space: normal;      /* long species names wrap instead of ellipsing */
    overflow: visible;
    text-overflow: clip;
    margin-bottom: 8px;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--cream-dim);
  }
  .modal.ri-chart-modal .ri-row .ri-col-axis {
    display: block;
    margin-bottom: 9px;
  }
  /* Bars grow a little — a 8px track is hard to read at arm's length. */
  .modal.ri-chart-modal .ri-row .ri-track {
    height: 11px;
    border-radius: 5.5px;
  }
  .modal.ri-chart-modal .ri-row .ri-bar.ri-dot {
    width: 11px;
    margin-left: -5.5px;
  }
  .modal.ri-chart-modal .ri-row .ri-track.combo-track {
    height: 22px;
    border-radius: 6px;
  }

  /* Numeric columns become inline labelled chips on one wrapping line. */
  .modal.ri-chart-modal .ri-row .ri-col-num {
    display: inline-block;
    margin: 0 14px 0 0;
    font-size: 12.5px;
    line-height: 1.4;
    text-align: left;
    color: var(--text-1);
  }
  .modal.ri-chart-modal .ri-row .ri-col-num::before {
    color: var(--text-3);
    font: 700 10px var(--font-ui);
    text-transform: uppercase;
    letter-spacing: 0.4px;
  }

  /* Field labels. Defaults below match the Refractive Index chart's column
     order (3 = RI, 4 = birefringence, 5 = critical angle); the combined
     chart shares 3 and 4. Each override carries the full
     `.modal.ri-chart-modal.<chart>` prefix so it outranks the default. */
  .modal.ri-chart-modal .ri-row > span:nth-child(3)::before { content: "RI — "; }
  .modal.ri-chart-modal .ri-row > span:nth-child(4)::before { content: "Biref. — "; }
  .modal.ri-chart-modal .ri-row > span:nth-child(5)::before { content: "Crit. ∠ — "; }
  /* Specific Gravity — single value column. */
  .modal.ri-chart-modal.sg-chart-modal .ri-row > span:nth-child(3)::before { content: "SG — "; }
  /* Hardness reuses the SG column set, so it carries an extra marker class
     (see openHardnessChart) to win over the .sg-chart-modal rule above. */
  .modal.ri-chart-modal.sg-chart-modal.mohs-chart-modal .ri-row > span:nth-child(3)::before { content: "Mohs — "; }
  /* Dispersion (Fire). */
  .modal.ri-chart-modal.disp-chart-modal .ri-row > span:nth-child(3)::before { content: "DI — "; }
  .modal.ri-chart-modal.disp-chart-modal .ri-row > span:nth-child(4)::before { content: "vs diamond — "; }
  /* RI + DI: 3 and 4 inherit RI / Biref. above; 5 and 6 are the fire pair. */
  .modal.ri-chart-modal.combo-chart-modal .ri-row > span:nth-child(5)::before { content: "DI — "; }
  .modal.ri-chart-modal.combo-chart-modal .ri-row > span:nth-child(6)::before { content: "vs diamond — "; }

  /* ================= Bar charts: toolbar ==================
     (.ri-toolbar already wraps with the search on its own row earlier in
     this file. These are the pieces that still overflowed.) */
  .ri-toolbar .ri-sort-group { flex: 0 0 auto; }
  /* The RI+DI legend is `white-space: nowrap` for the desktop toolbar —
     on a phone it has to wrap onto its own line. */
  .ri-toolbar .combo-legend {
    flex: 1 1 100%;
    white-space: normal;
    line-height: 1.6;
    font-size: 11px;
  }
  /* Dispersion "Curve" view: the material picker carries an inline
     max-width:230px for the desktop toolbar — override it and let the plot
     take the height the row list would have had. */
  .ri-toolbar #dpCurveMat {
    flex: 1 1 100%;
    max-width: none !important;
  }
  .modal.ri-chart-modal #dpCurve {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
  }

  /* ================= Bar charts: footer ==================
     The source note is 2–4 sentences; full-width and capped so it can't
     push the Close button off-screen. */
  .modal.ri-chart-modal .modal-foot.ri-foot {
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 14px;
  }
  .modal.ri-chart-modal .ri-foot .ri-note {
    flex: 1 1 100%;
    max-height: 4.4em;
    overflow-y: auto;
    font-size: 11px;
    line-height: 1.45;
  }
  .modal.ri-chart-modal .ri-foot .btn { flex: 1 1 100%; }

  /* ================= User Manual ==================
     The 210px sidebar becomes a horizontally-scrollable strip of section
     chips pinned above the text; the content pane then gets the full
     width. The existing scroll-spy keeps highlighting the active chip
     (it only toggles .active, which is styled below), and the TOC links
     still jump-scroll #manualContent, so no JS changes are needed. */
  .man-wrap { flex-direction: column; }
  .man-toc {
    flex: 0 0 auto;
    display: flex;
    gap: 6px;
    padding: 9px 12px;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    border-right: none;
    border-bottom: 1px solid var(--border-soft);
  }
  .man-toc::-webkit-scrollbar { display: none; }
  .man-toc-head { display: none; }
  .man-toc-link {
    flex: 0 0 auto;
    margin: 0;
    padding: 7px 13px;
    font-size: 12.5px;
    white-space: nowrap;
    background: var(--bg-3);
    border: 1px solid var(--border-soft);
    border-radius: 999px;
  }
  .man-toc-link.active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
  }
  .man-content { padding: 4px 16px 48px; }

  /* Body copy: the desktop 12.5–13px is too small to read on a phone. */
  .man-sec { padding-top: 18px; }
  .man-sec h3 { font-size: 18px; margin-bottom: 12px; }
  .man-sec h4 { font-size: 13px; }
  .man-sec p,
  .man-sec li { font-size: 14.5px; line-height: 1.65; }
  .man-sec ul { padding-left: 18px; }
  .man-gloss dt { font-size: 14px; }
  .man-gloss dd { font-size: 14px; line-height: 1.6; }
  .man-ex-note { font-size: 13.5px; line-height: 1.6; }
  .man-ex-step { padding-left: 11px; }
  .man-ex-step h5 { font-size: 14px; }

  /* Figures, screenshots and the SVG diagrams all fit the column. */
  .man-fig { padding: 10px; margin: 12px 0 14px; }
  .man-fig-svg,
  .man-fig-svg.tall { max-width: 100%; }
  .man-fig-cap { font-size: 12px; }
  .man-shot-img { max-width: 100%; height: auto; }
  .man-shot figcaption { font-size: 12px; }
  .man-ex .man-shot,
  .man-ex-step .man-shot { max-width: 100%; }

  /* Shortcut table: key(s) left, description right, wrapping when tight. */
  .man-kbrow {
    flex-wrap: wrap;
    gap: 4px 14px;
    padding: 7px 0;
    font-size: 13.5px;
  }
  .man-kbrow > span:first-child { flex: 0 0 auto; }
  .man-kbrow > span:last-child { flex: 1 1 auto; text-align: right; }

  .modal.manual-modal .modal-foot {
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 14px;
  }
  .man-foot-note { flex: 1 1 100%; font-size: 10.5px; }
  .modal.manual-modal .modal-foot .btn { flex: 1 1 100%; }
}
