/* ── one-orange.css ── */
/*
 * One orange thing per screen — and it is the voice.
 *
 * WHY
 * Orange was on everything: the top promo strip, the bottom bar, the chat pill,
 * "Start Earning", "Log In", the ScanSquad avatar. Measured live at phone width,
 * Book, Partner and Profile each painted three orange surfaces. On Partner two of
 * them were both "Ask AI"; on Profile "Log In" and "Continue - Sign in to unlock
 * your QR pass" were both sign-in. The same action, twice, in the loudest colour.
 * When everything is the primary action, nothing is.
 *
 * Worse, #sg-usp-banner is orange and cannot be clicked at all, so the brightest
 * thing on the page was not an action.
 *
 * THE RULE
 * Orange marks the one thing we want you to do. The product's whole premise is
 * that you say what you want rather than hunting for a button, so the voice
 * affordance keeps the orange and every other call to action steps down to a
 * legible neutral. Nothing is hidden or disabled — tapping still works exactly as
 * before, it simply stops shouting over the microphone.
 *
 * HOW
 * This file loads last and uses !important because the colours it overrides are
 * inline gradients written by a dozen different scripts. Restyling each of those
 * call sites would touch app.ctr576.js, round4-ui.js, continue-cta-flow.js,
 * partner-editable.js and more; a single late stylesheet is reversible by deleting
 * one <link>, which matters more here than purity.
 */

:root {
  /* Neutral for demoted actions: reads as a real button on the dark theme,
     clearly secondary next to orange, still WCAG-legible against #0f172a. */
  --sg-secondary-bg: #1e293b;
  --sg-secondary-bg-hover: #334155;
  --sg-secondary-border: #475569;
  --sg-secondary-fg: #e2e8f0;
}

/* ─── 1. The one orange thing: the voice pill ────────────────────────────────
   Left orange on purpose, and lifted slightly so it reads as the primary
   action now that it no longer competes with three other orange surfaces. */
#bchat-fab,
#pchat-fab,
#schat-fab,
#rchat-fab,
#mchat-fab,
#chat-fab {
  background: linear-gradient(135deg, #FF6D00, #E66200) !important;
  color: #fff !important;
  box-shadow: 0 6px 24px rgba(255, 109, 0, .38) !important;
  font-weight: 700 !important;
}

/* ─── 2. The promo strip is information, not an action ──────────────────────
   It cannot be clicked, so it must not wear the colour that means "press me". */
#sg-usp-banner {
  background: #111827 !important;
  background-image: none !important;
  color: #cbd5e1 !important;
  border-bottom: 1px solid #1f2937 !important;
}

/* ─── 3. Bottom bar: still the tap path, no longer the loudest thing ────────
   This is the duplicate on Partner ("Ask AI" twice) and Profile ("Log In" plus
   "Sign in"). Demoted rather than deleted: the tap route keeps working for
   anyone who cannot or does not want to speak, which includes every visitor
   with the microphone blocked. */
#sg-continue-banner {
  background: var(--sg-secondary-bg) !important;
  background-image: none !important;
  color: var(--sg-secondary-fg) !important;
  border-top: 1px solid var(--sg-secondary-border) !important;
  box-shadow: none !important;
}
#sg-continue-banner * {
  color: var(--sg-secondary-fg) !important;
}

/* ─── 4. In-page primaries step down ────────────────────────────────────────
   "Start Earning" (ScanSquad) and anything using the brand fill, e.g. "Log In". */
#join-btn,
#sg-aff-continue-btn,
.bg-brand:not(#bchat-fab):not(#pchat-fab):not(#schat-fab):not(#rchat-fab):not(#mchat-fab) {
  background: var(--sg-secondary-bg) !important;
  background-image: none !important;
  color: var(--sg-secondary-fg) !important;
  border: 1px solid var(--sg-secondary-border) !important;
  box-shadow: none !important;
}
#join-btn:hover,
#sg-aff-continue-btn:hover,
.bg-brand:not(#bchat-fab):not(#pchat-fab):not(#schat-fab):not(#rchat-fab):not(#mchat-fab):hover {
  background: var(--sg-secondary-bg-hover) !important;
}

/* ─── 5. Decoration should never be orange ──────────────────────────────────
   The ScanSquad avatar is an identity chip, not a button, but it was pulling
   the eye as hard as the real call to action beside it. */
.dash-avatar {
  background: var(--sg-secondary-bg) !important;
  background-image: none !important;
  color: var(--sg-secondary-fg) !important;
  border: 1px solid var(--sg-secondary-border) !important;
}

/* ─── 6. The catch-all: orange written straight into a style attribute ──────
   The first pass of this file missed two elements, and the live audit caught
   them: the ScanSquad avatar and Profile's "Log In" button both carry
   `background:#FF6D00` inline with no id and no class, so there was nothing to
   select them by.
   Matching the style attribute itself fixes those two and, more usefully, any
   future element that paints itself brand orange inline — which is how every
   one of these got here. Restricted to `background`, so an element merely using
   orange for text or a border is left alone, and the pills are exempt. */
[style*="background:#FF6D00"]:not([id$="-fab"]),
[style*="background: #FF6D00"]:not([id$="-fab"]),
[style*="background:#FF6D00"] :not([id$="-fab"]),
[style*="background:linear-gradient(135deg,#FF6D00"]:not([id$="-fab"]),
[style*="background: linear-gradient(135deg, #FF6D00"]:not([id$="-fab"]) {
  background: var(--sg-secondary-bg) !important;
  background-image: none !important;
  color: var(--sg-secondary-fg) !important;
  box-shadow: none !important;
}

/* The "Finding new gyms…" toast is a status message, not something to press. */
#sg-pull-refresh {
  background: rgba(30, 41, 59, .95) !important;
  background-image: none !important;
  color: var(--sg-secondary-fg) !important;
}

/* ─── 7. Respect reduced motion on the pill's live dot ──────────────────────
   The pill is now the single focal point, so its pulse is more noticeable. */
@media (prefers-reduced-motion: reduce) {
  #bchat-fab .pchat-fab-dot,
  #pchat-fab .pchat-fab-dot,
  #schat-fab .pchat-fab-dot,
  #rchat-fab .pchat-fab-dot,
  #mchat-fab .pchat-fab-dot {
    animation: none !important;
  }
}

/* ─── 8. The two the static tests could never see ───────────────────────────
   Sections 1–7 were written by reading the source. These two were found by
   driving the live site in a mobile browser and counting the orange surfaces
   the user can actually see — which is the only measurement that matches the
   rule. Both escaped every existing test because those tests grep this
   stylesheet, and an element that was never added to this stylesheet is
   invisible to them.

   8a. #sg-sps — the "No membership needed · Instant QR · Free cancel" strip.
   app-patches-v3.js injects it three seconds after paint with an orange wash
   and an orange bottom border, full width, directly above the content. It is
   reassurance copy, not a call to action, and on Book and Profile it was the
   second orange surface on the screen. Keep the strip, drop the orange. */
#sg-sps {
  background: var(--sg-secondary-bg) !important;
  border-bottom-color: rgba(255, 255, 255, .10) !important;
}

/* ─── The location prompt ────────────────────────────────────────────────────
   #sg-location-banner is a full-width bar at the very top of Book, and it is
   orange — but as a gradient in the amber family, rgb(120,53,15) to
   rgb(146,64,14), not #FF6D00. Every rule above keys on the brand hex, so
   nothing here caught it and no static test could: the colour is set inline
   from JS. A rendered-page audit is what found it.

   It reads as a second orange bar on the tab. Keep the prompt, drop the hue. */
#sg-location-banner {
  background-image: none !important;
  background-color: var(--sg-secondary-bg) !important;
  border-bottom: 1px solid rgba(255, 255, 255, .10) !important;
}


/* ── one-button.css ── */
/*
 * One button look, everywhere. (owner, 2026-09-19)
 *
 * WHY
 * "Why in reels tab below button are not same colour, same looking like share
 *  button or search button — book button, talk button, ask AI button? Same in
 *  book tab, scansquad tab, partner tab."
 *
 * Because five different places each painted their own circle, and no two of
 * them agreed. Read off the source, not guessed:
 *
 *   reels/index.html  .reel-action .icon   44px  rgba(0,0,0,.4)      border 1.5px .12  blur 12px  22px SVG
 *   sg-rail-ui.js     .sg-rr-circle        44px  rgba(20,20,35,.72)  border 1px   .14  blur 12px  20px SVG
 *   sg-rail-ui.js     .tt-action-btn.sgi   42px  rgba(13,16,25,.62)  border 1px   .09  blur  6px  20px SVG
 *   sg-scansquad.js   .creator-side-btn    42px  purple/green/orange tints, inline   blur  8px  COLOUR EMOJI
 *   rails.js          .sg-row-trio         42px  rgba(13,16,25,.62)  border 1px   .10  no blur   COLOUR EMOJI
 *
 * and two more rails found on the second pass, once he said "all remaining
 * button also":
 *
 *   profile-rail.js   .sg-pr-circle        44px  rgba(0,0,0,.4)      border 1px   .12  blur 12px  22px SVG
 *   squad-create.js   .sv-circle           44px  rgba(255,109,0,.18) border 1px orange  blur 12px  19px EMOJI + orange glow
 *
 * plus three caption styles: 10px/600 full white (Reels), 9px/700 full white
 * (ScanSquad, reels rail), 10px/600 at 72% white (Book / Talk / Ask AI). So the
 * trio always read bigger, greyer and — because of the emoji — in a different
 * colour family from the Share, Save, Search, Near me and Verify buttons sitting
 * right beside it, and ScanSquad's rail was four different colours at once.
 *
 * rails.css already carried a "THE SAME THREE BUTTONS, THE SAME LOOK, EVERY TAB"
 * section (2026-09-18). It could not deliver that, because it *restated* the
 * numbers for one row instead of sharing them: every one of the differences
 * above is a copy that drifted from the copy it was taken from.
 *
 * THE RULE
 * The circle and its caption are defined once — here — as custom properties.
 * Every row consumes them with var(). Changing the strip's look is changing one
 * number in one file, and no row can be "nearly" the same again.
 *
 * WHICH LOOK WON
 * Reels' Share/Save, because that is the button he is comparing everything to
 * and because the buttons over video are the hardest case: 44px, real blur,
 * full-white caption. The flatter 42px Book/Partner circle is the one that
 * looked cheap next to it.
 *
 * WHAT IS NOT DECIDED HERE
 * Position, band size, which buttons exist, and who is orange. Those stay in
 * rails.css, sg-rail-ui.js and one-orange.css. This file decides only what a
 * strip button looks like once something else has put it there.
 *
 * WHY THE !important BELOW IS ONLY ON TWO BLOCKS
 * The rows that live in stylesheets read these properties directly, so they need
 * no override at all. The two that do are ScanSquad's rail, which writes its
 * colours into style attributes from JS, and nothing else — an inline style can
 * only be beaten with !important.
 *
 * REVERSIBILITY
 * One file, one <link> per document. Delete the link and every row falls back to
 * the var() fallbacks next to it, which are this file's values, so the app stays
 * consistent even without it; nothing is unwired and no button moves.
 */

:root {
  /* The circle. */
  --sg-btn-size: 44px;
  /* Owner 2026-10-04 "home and create tab button same theme": these three no
     longer carry their own values — they read the one row theme in
     sg-row-theme.css, so every circle in every row matches Home and Create.
     The fallbacks keep this file standalone if it is ever loaded alone. */
  --sg-btn-bg: rgba(255, 255, 255, .07);
  --sg-btn-border-width: 1px;
  --sg-btn-border-color: rgba(255, 255, 255, .16);
  --sg-btn-blur: blur(8px);
  --sg-btn-shadow: 0 2px 10px rgba(0, 0, 0, .25);
  /* 20px, the owner's call (2026-09-19). Reels' Share/Save were drawn at 22px
     and every rail behind them at 20px, so one of the two had to move; the
     smaller icon is the one four of the six rows already used. */
  --sg-btn-icon: 20px;           /* the SVG; also the emoji size where one is left */
  --sg-btn-gap: 3px;             /* circle → caption */

  /* The caption. Full white: 72% white over a bright frame of video is the one
     that disappears, which is why the Reels labels were already at 100%. */
  --sg-btn-label-size: 10px;
  --sg-btn-label-weight: 600;
  --sg-btn-label-color: #fff;
  --sg-btn-label-shadow: 0 1px 4px rgba(0, 0, 0, .8);
  --sg-btn-label-tracking: .2px;
}

/* ─── ScanSquad's creator rail ──────────────────────────────────────────────
   Five buttons, five inline tints: orange Sign in, purple Get link, green
   Withdraw, orange Deep link, white More — each with its own border and its own
   glow. It was the least consistent row in the app and the reason the tab does
   not look like Reels. The tints carry no meaning (they are not status; the
   green Withdraw is not "successful"), so they go, and the buttons become the
   same button as everywhere else. Inline styles, so !important is the only
   lever. */
.creator-side-btn {
  width: var(--sg-btn-size) !important;
  height: var(--sg-btn-size) !important;
  border-radius: 50% !important;
  background: var(--sg-btn-bg) !important;
  background-image: none !important;
  border: var(--sg-btn-border-width) solid var(--sg-btn-border-color) !important;
  -webkit-backdrop-filter: var(--sg-btn-blur) !important;
  backdrop-filter: var(--sg-btn-blur) !important;
  box-shadow: var(--sg-btn-shadow) !important;
  color: #fff !important;
  font-size: var(--sg-btn-icon) !important;
  letter-spacing: 0 !important;
}

.creator-side-btn svg {
  width: var(--sg-btn-icon) !important;
  height: var(--sg-btn-icon) !important;
  stroke: currentColor !important;
}

/* ─── The "More" button is a strip button, not a brand surface ──────────────
   sg-rail-ui.js painted it orange (rgba(255,109,0,.2)) in one rule and
   neutralised it again in a later one — two rules, opposite answers, same file,
   and whichever one the reader found first was wrong. Both are deleted there;
   this is the single answer, and it is the same one every other button gets. */
.tt-action.sgi-more .tt-action-btn {
  background: var(--sg-btn-bg);
  border: var(--sg-btn-border-width) solid var(--sg-btn-border-color);
}

/* ─── Two rails that were missed on the first pass ──────────────────────────
   profile-rail.js had the right values already, arrived at separately: same
   44px, same rgba(0,0,0,.4), same blur — with a 1px border instead of 1.5px and
   a 22px icon. Being right by coincidence is still a copy, so it reads the
   properties now like everything else.

   squad-create.js's button was orange-tinted with an orange glow, which made it
   read as the primary action on a screen where it is not, and collided with the
   one-orange rule (the voice pill is the orange thing). The live/soon dot still
   carries its state — the tint never did. */
.sg-pr-circle,
#sg-profile-rail .sg-pr-circle {
  width: var(--sg-btn-size);
  height: var(--sg-btn-size);
  background: var(--sg-btn-bg);
  border: var(--sg-btn-border-width) solid var(--sg-btn-border-color);
  -webkit-backdrop-filter: var(--sg-btn-blur);
  backdrop-filter: var(--sg-btn-blur);
  box-shadow: var(--sg-btn-shadow);
}

.sg-pr-circle svg,
#sg-profile-rail .sg-pr-circle svg {
  width: var(--sg-btn-icon);
  height: var(--sg-btn-icon);
}

.sv-circle {
  width: var(--sg-btn-size) !important;
  height: var(--sg-btn-size) !important;
  background: var(--sg-btn-bg) !important;
  border: var(--sg-btn-border-width) solid var(--sg-btn-border-color) !important;
  -webkit-backdrop-filter: var(--sg-btn-blur) !important;
  backdrop-filter: var(--sg-btn-blur) !important;
  box-shadow: var(--sg-btn-shadow) !important;
  font-size: var(--sg-btn-icon) !important;
  color: #fff !important;
}

.sv-circle svg {
  width: var(--sg-btn-icon) !important;
  height: var(--sg-btn-icon) !important;
  stroke: currentColor !important;
}

/* ─── Deliberately NOT in here ──────────────────────────────────────────────
   chat-agent.js's .pchat-rnd (the mic and send buttons in the chat composer).
   They are 44px circles too, but they sit on a solid #0b0b14 sheet inside a
   panel, not over content: glass has nothing to blur there, and send is the
   primary action of that panel. Same for avatars, unread dots, spinners, the
   voice pill (one-orange.css) and the admin and partner dashboards, which are
   desktop surfaces with their own buttons. This file governs the round action
   buttons that sit over the app's content. */

/* ─────────────────────────────────────────────────────────────────────────
 * Tap targets and text size on the horizontal pill rows (Photos, Trainer).
 *
 * Audited live on www.scangym.com at 390x844: every pill in `.sg-pills-row`
 * measured 36px tall, and the Trainer row's labels were 11px — the only text
 * in the app under 12px. Both numbers are written inline by the render
 * functions in app.ctr576.js (one per tab, drifted from each other), so they
 * are corrected here in the one place that owns button looks rather than in
 * two template strings.
 *
 * !important is required: the sizes being overridden are inline styles.
 * Minimum tap target 44x44 (Apple HIG / Material), minimum body text 12px.
 * ───────────────────────────────────────────────────────────────────────── */
.sg-pills-row button {
  min-height: 44px !important;
  font-size: 12px !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}


/* ── sg-row-theme.css ── */
/* ═══════════════════════════════════════════════════════════════════════════
   sg-row-theme.css — ONE definition of the see-through button row, for every
   tab (owner, 2026-10-04: "Every button is transparent or see through and at
   bottom … home and create tab button same theme").

   Why this file exists
   --------------------
   The glass look had grown three different recipes, so "same theme" was not
   true on the device:

     Home / Create rows ....... rgba(20,20,26,.20) + 1px rgba(255,255,255,.16) + blur(8px)
     sg-glass.css (chips) ..... rgba(255,255,255,.10) + 1px rgba(255,255,255,.22) + blur(14px)
     rails.css (SPA band) ..... rgba(0,0,0,.40)      + 1px rgba(255,255,255,.12) + blur(12px)

   The owner picked the Home/Create look, so those values are the tokens here
   and the other two files now read them instead of carrying their own. Change
   a row's colour HERE; a second opinion in another file is what produced the
   drift in the first place.

   What the research changed (proven practice, not taste)
   ------------------------------------------------------
   - Apple, "Adopting Liquid Glass" + WWDC25: the bar floats above content and
     stays pinned. That is the shape we already use.
   - backdrop-filter is the top cause of mobile scroll jank, and the area it
     samples grows ~3x the radius per side. So: blur lives on the *chrome*
     only — never on a scroll container or per card — and 8px, not 14-18px.
   - Always ship a fallback: @supports for browsers without backdrop-filter,
     and solid surfaces for prefers-reduced-transparency / prefers-contrast.
     Apple treats Reduce Transparency as a requirement, not a nicety.
   - Bottom bars clear env(safe-area-inset-bottom).
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* the row itself */
  --sg-row-bg: rgba(20, 20, 26, .20);
  --sg-row-edge: rgba(255, 255, 255, .16);
  --sg-row-blur: blur(8px);
  --sg-row-radius: 999px;
  --sg-row-pad: 6px;

  /* a button inside the row */
  --sg-row-btn-bg: rgba(255, 255, 255, .07);
  --sg-row-btn-edge: rgba(255, 255, 255, .16);

  /* the selected state — the one place colour is allowed */
  --sg-row-on: rgba(255, 109, 0, .78);
  --sg-row-on-edge: rgba(255, 170, 100, .9);

  /* brand */
  --sg-orange: #FF6D00;
}

/* ── the utility every new screen uses ─────────────────────────────────────
   A row is: fixed, full width minus 8px either side, pinned above the tab bar,
   one glass layer, and it scrolls sideways instead of wrapping or squeezing. */
.sg-row {
  position: fixed;
  left: 8px;
  right: 8px;
  z-index: 26;
  display: flex;
  align-items: center;
  padding: var(--sg-row-pad);
  border-radius: var(--sg-row-radius);
  background: var(--sg-row-bg);
  border: 1px solid var(--sg-row-edge);
  -webkit-backdrop-filter: var(--sg-row-blur);
  backdrop-filter: var(--sg-row-blur);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x;
}
.sg-row::-webkit-scrollbar { display: none; }
.sg-row > * { flex: 0 0 auto; scroll-snap-align: start; }

/* Buttons in a row: see-through, never solid. */
.sg-row-btn {
  background: var(--sg-row-btn-bg);
  border: 1px solid var(--sg-row-btn-edge);
  color: #fff;
  /* 44px is the smallest reliable touch target on both platforms. */
  min-height: 44px;
  border-radius: var(--sg-row-radius);
}
.sg-row-btn[aria-selected="true"],
.sg-row-btn.on {
  background: var(--sg-row-on);
  border-color: var(--sg-row-on-edge);
}

/* The bottom-most row clears the home indicator / gesture bar. */
.sg-row.sg-row-bottom {
  bottom: calc(var(--sg-nav-h, 56px) + env(safe-area-inset-bottom, 0px) + 12px);
}

/* ── fallbacks ────────────────────────────────────────────────────────────
   1. No backdrop-filter (older Android WebView, Firefox without the flag):
      a translucent row over video is unreadable without the blur, so go
      opaque instead of pretending. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  :root {
    --sg-row-bg: rgba(16, 16, 22, .88);
    --sg-row-btn-bg: rgba(255, 255, 255, .12);
  }
}

/* 2. The user asked the OS for less transparency, or more contrast: give them
      solid surfaces and a brighter edge. Same geometry, no glass. */
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  :root {
    --sg-row-bg: #101016;
    --sg-row-edge: rgba(255, 255, 255, .34);
    --sg-row-btn-bg: rgba(255, 255, 255, .16);
    --sg-row-btn-edge: rgba(255, 255, 255, .34);
    --sg-row-blur: none;
    --sg-row-on: #FF6D00;
  }
  .sg-row,
  .tt-actions,
  .reel-actions,
  #sg-sv-rail.sv-float {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
}

/* 3. Low-power / small screens: keep the blur but never let it grow. */
@media (max-width: 480px) {
  :root { --sg-row-blur: blur(8px); }
}

/* ── v3.0 · CTO Rule 8: ONE button, every tab ─────────────────────────────
   Live audit 2026-10-05 found the pills in the bottom rows still disagreed:
   Home 40px system-ui, Shop chips 29px Arial, Chats 40px -apple-system with a
   per-button blur(14px), Home icons colour emoji while every other row used
   white line icons. One recipe now, read from the tokens above:
   40px pill · 13px/600 one font · token glass · 1px token edge · no per-button
   blur (the row already blurs — per-button blur is the jank the research warns
   about) · white 16px line icon · orange only for the selected state.
   The Create row (#sg-sv-rail) is deliberately NOT listed: owner signed it off. */
:root { --sg-font: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, system-ui, sans-serif; }
html body #reels-cat-rail button.reels-cat,
html body #actions button.chip,
html body #sg-chats-row .seg button,
html body #sg-chats-row .tabs#filters button {
  height: 40px !important; min-height: 40px !important;
  display: inline-flex !important; align-items: center; gap: 6px;
  padding: 0 14px !important; border-radius: 999px !important;
  font: 600 13px/1 var(--sg-font) !important; color: #fff !important; text-shadow: none !important;
  background: var(--sg-row-btn-bg) !important; border: 1px solid var(--sg-row-btn-edge) !important;
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}
html body #reels-cat-rail button.reels-cat[aria-selected="true"],
html body #actions button.chip[aria-selected="true"],
html body #sg-chats-row .seg button.on {
  background: var(--sg-row-on) !important; border-color: var(--sg-row-on-edge) !important;
}
/* CTO Rule 8 v1.0: one solid orange per row. On Chats the section (Chats /
   Calls / Tools) owns it; the chosen filter is glass with an orange edge. */
html body #sg-chats-row .tabs#filters button.on {
  background: var(--sg-row-btn-bg) !important; border-color: var(--sg-row-on-edge) !important; color: #FF8A33 !important;
}
/* CTO Rule 8 v1.0: the Profile row uses the same 40px glass pill as Home,
   Shop and Chats instead of icons stacked over captions. */
html body .sg-pr-host-capped > .sg-row-slot > .tt-action.sg-row-trio,
html body .sg-pr-host-capped > button,
html body .sg-pr-host-capped > div[onclick],
html body .sg-pr-host-capped #sg-profile-rail-ext .sg-pr-btn {
  width: auto !important;
  flex: 0 0 auto !important; flex-direction: row !important; align-items: center !important; gap: 6px !important;
  height: 40px !important; min-height: 40px !important; padding: 0 14px 0 10px !important; border-radius: 999px !important;
  background: var(--sg-row-btn-bg) !important; border: 1px solid var(--sg-row-btn-edge) !important;
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}
html body .sg-pr-host-capped > .sg-row-slot > .tt-action.sg-row-trio > .tt-action-btn,
html body .sg-pr-host-capped > button > :first-child,
html body .sg-pr-host-capped > div[onclick] > :first-child,
html body .sg-pr-host-capped #sg-profile-rail-ext .sg-pr-circle {
  width: 20px !important; height: 20px !important; min-width: 0 !important; margin: 0 !important; border-radius: 0 !important; position: relative;
  background: transparent !important; border: 0 !important; box-shadow: none !important;
}
html body .sg-pr-host-capped > .sg-row-slot > .tt-action.sg-row-trio > .tt-action-btn svg,
html body .sg-pr-host-capped > button > :first-child svg,
html body .sg-pr-host-capped > div[onclick] > :first-child svg,
html body .sg-pr-host-capped #sg-profile-rail-ext .sg-pr-circle svg { width: 16px !important; height: 16px !important; }
html body .sg-pr-host-capped > .sg-row-slot > .tt-action.sg-row-trio > .tt-action-label,
html body .sg-pr-host-capped > button > span:last-child,
html body .sg-pr-host-capped > div[onclick] > :last-child,
html body .sg-pr-host-capped #sg-profile-rail-ext .sg-pr-label {
  font: 600 13px/1 var(--sg-font) !important; color: #fff !important; text-shadow: none !important; margin: 0 !important; white-space: nowrap !important;
  /* CTO Rule 8 v2.0 round 2: an old 60px label cap clipped "Ask Gymo" to
     "Ask Gy…" on Profile. Pills size to their label like every other row. */
  max-width: none !important; overflow: visible !important; text-overflow: clip !important;
}
html body #reels-search-button,
html body #sg-chats-row .hic button,
html body #sg-chats-row .fab {
  width: 40px !important; height: 40px !important; min-height: 40px !important; border-radius: 999px !important;
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}
html body #reels-search-button,
html body #sg-chats-row .hic button {
  background: var(--sg-row-btn-bg) !important; border: 1px solid var(--sg-row-btn-edge) !important; color: #fff !important;
}
html body #actions .act, html body #actions .act .lb { font-family: var(--sg-font); }
.sg-ci { display: inline-flex; width: 16px; height: 16px; }
.sg-ci svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* CTO Rule 8 v9.1 (owner 2026-10-06: "read Rule 8 again for every tab"). A live
   audit found the last odd ones out: Shop's action pills were 32px next to 40px
   chips; Home's search was a 50% circle with its own glass; Chats' search had no
   glass or edge; Chats' Sign in used another font/edge; Chats' New chat was a
   second solid orange in a row whose section already owns the orange. All of
   them now take the same 40px token glass pill, 13px/600 Inter, white icon. */
html body #actions button.act {
  height: 40px !important; min-height: 40px !important; padding: 0 14px !important;
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}
html body #reels-cat-rail button#reels-search-button,
html body #sg-chats-row button.sg-cs-btn,
html body #sg-chats-row button.fab,
html body #sg-chats-row .fab {
  width: 40px !important; height: 40px !important; min-height: 40px !important; border-radius: 999px !important;
  background: var(--sg-row-btn-bg) !important; border: 1px solid var(--sg-row-btn-edge) !important; color: #fff !important;
  box-shadow: none !important; -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}
html body #sg-chats-row button.sg-cs-btn svg { stroke: #fff; }
html body #sg-chats-row a.sg-signin {
  height: 40px !important; min-height: 40px !important; display: inline-flex !important; align-items: center;
  padding: 0 14px !important; border-radius: 999px !important;
  font: 600 13px/1 var(--sg-font) !important; color: #fff !important;
  background: var(--sg-row-btn-bg) !important; border: 1px solid var(--sg-row-btn-edge) !important;
}


/* ── one-cta.css ── */
/*
 * One call to action per tab — and it is the voice.
 *
 * WHY
 * one-orange.css made the voice pill the only *orange* thing. That fixed the
 * colour clash but not the underlying problem: the tabs still offered several
 * competing things to press. Measured live at phone width after that change:
 *
 *   Reels 1 · Book 2 · ScanSquad 3 · Partner 3 · Profile 5
 *
 * Profile alone asked you to log in, verify your ID, continue, and talk. The
 * product's premise is that you say what you want and it happens, so every extra
 * button is a second answer to a question that should only have one.
 *
 * THE RULE
 * Each tab surfaces exactly one call to action: the Talk pill. Everything else
 * that asked to be pressed is removed from the surface.
 *
 * WHAT IS DELIBERATELY KEPT
 *   - Navigation is not a call to action. The bottom tab bar and the Profile
 *     "Back to More" link stay: removing the way out of a screen strands people.
 *   - Information stays. The price summary and the partner's gym name remain
 *     visible; the gym name simply stops being tappable, so it informs without
 *     competing.
 *   - The Talk panel keeps its "Type instead" option. This is the important one:
 *     a tab with no tap buttons would be a dead end for anyone whose microphone
 *     is blocked, unsupported, or who simply cannot speak right now. One CTA on
 *     the surface, never a dead end underneath.
 *
 * REVERSIBILITY
 * Everything here is display:none on a handful of ids, in one file, loaded last.
 * Deleting a rule brings a button back exactly as it was; nothing is unwired.
 * Note that #sg-continue-banner carries the *purchase* action on Book, so this
 * file is where booking-by-tap went. That was an explicit product decision, and
 * it is one line to undo.
 */

/* ─── The bottom bar: "Book this gym", "Continue", "Ask AI …" ───────────────
   One bar, three different second-best answers depending on the tab. */
#sg-continue-banner {
  display: none !important;
}

/* ─── Profile: the secondary prompts ────────────────────────────────────────
   "Get ID verified" and the orange "Log In" button. Both are things the voice
   can start on request, and neither needs to shout on arrival. The button has
   no id or class, so it is matched by the brand orange it paints inline. */
#sg-id-row,
button[style*="background:#FF6D00"],
button[style*="background: #FF6D00"] {
  display: none !important;
}
/* …but not inside a sheet the customer opened on purpose. The rule above also
   matched the Shop's "Buy for £X" button (and the reel Shop sheet's day-pass
   button), so a product sheet had no way to pay (found 2026-09-30, task 6).
   A sheet is one decision, and its orange button IS the one CTA. */
.shs-body button[style*="background:#FF6D00"],
#sg-shop-sheet button[style*="background:#FF6D00"],
/* Task 154: a logged-out Profile with no way to log in was a dead end. */
#sg-profile-login {
  display: block !important;
}

/* ─── ScanSquad: "Start Earning" and the affiliate-link chip ────────────────
   Both are reachable by saying so; the chip in particular was a second primary
   sitting in the header, above the fold, before you had done anything. */
#join-btn,
#sg-aff-continue-btn,
.affiliate-btn {
  display: none !important;
}

/* ─── Partner: the gym name stays, but stops being a button ─────────────────
   Hiding it would remove the one piece of information telling a partner which
   gym they are looking at. Keeping it inert preserves that while removing the
   invitation to press it — "change my gym address" is a sentence, not a tap. */
#partner-name-display {
  pointer-events: none !important;
  cursor: default !important;
}

/* ─── The one that stays ────────────────────────────────────────────────────
   Nothing here. Stated on purpose.

   This block used to force the pills visible with `display:inline-flex`, to make
   it obvious which element survives. That was a mistake and it shipped: in the
   SPA all five personalities are loaded, each builds its own pill, and
   chat-agent.js hides the four that do not belong to the current tab. Forcing
   display overrode that and put five "Talk" buttons on Book, Partner and
   Profile at once — the exact opposite of one call to action.

   The pill does not need a rule to survive. It survives because this file never
   hides it. Do not "helpfully" add one back. */

/* ─── The four the earlier passes missed, all on Profile ────────────────────
   Reported from the live app and then confirmed in source:

     "Get Your QR Pass →"          #sg-qr-pass-cta    app.ctr576.js
     "I already have an account"   #sg-login-alt      app.ctr576.js
     "Join ScanSquad → 25% …"      #sg-bottom-popup   app.ctr576.js
     "See how it works →"          #sg-how-it-works   sg-scansquad.js

   None of them had an id, so there was nothing to select; the ids above were
   added alongside this rule for exactly that reason.

   Why every earlier audit missed them, including an automated one: they sit
   below the fold, or arrive on a timer after first paint. An audit that only
   inspects the viewport shortly after load reports the page as clean. Anything
   measuring "one CTA per tab" has to scroll the full page and has to wait —
   tools/brand-audit.js now does both.

   Note "Get Your QR Pass" paints itself with a *gradient*
   (linear-gradient(135deg,#FF6D00,#ff8533)), so the existing
   button[style*="background:#FF6D00"] rule above never matched it. A flat
   colour was demoted and the gradient beside it was not.

   All four are removed as buttons, not as features: signing in, joining
   ScanSquad and fetching a QR pass are all things the voice agent already
   does. You get them by saying so. */
#sg-qr-pass-cta,
#sg-login-alt,
#sg-how-it-works,
#sg-bottom-popup {
  display: none !important;
}


/* ── brand-mark.css ── */
/* ═══════════════════════════════════════════════════════════════════════════
   brand-mark.css — one orange circle logo, in the same place, on every tab.

   Why a file of its own rather than a few lines in one-orange.css: that file
   is the colour layer, and its tests enforce that it only ever *recolours* —
   it may not hide an element and may not set pointer-events, because doing
   either to a call to action would strand anyone who cannot use a microphone.
   Both of those are exactly what a logo needs. Different job, different file.

   What was actually on the live site (mobile viewport, full page, 2026-08-27):

     Reels      5 orange circle logos   one per reel card, several cards in the DOM
     ScanSquad  1
     Book       0
     Partner    0
     Profile    0

   Five, one, or none, depending on the tab — "different branding on each tab".
   The mark was never wrong; its *placement* was, because it was attached to
   feed cards whose number varies instead of to the app.

   So: paint it once, on the page itself, in a fixed position. Every tab gets
   exactly one and it lands in the same spot on all five, regardless of what is
   rendered underneath. The disc is unchanged from the original — 28px, brand
   orange, white "S", same soft glow.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Owner 2026-10-04: "Even logo 🟠 orange border transparent or see through in
   all tabs. No S inside just orange border." So the disc keeps its place and
   its size and loses the letter: an empty see-through ring in brand orange,
   the same glass the button rows use. */
body::before {
  content: '';
  position: fixed;
  top: max(14px, env(safe-area-inset-top, 0px));
  left: 14px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  /* Owner 2026-10-04: see-through glass disc with an orange border, like the pills. */
  box-sizing: border-box;
  background: var(--sg-row-bg, rgba(20, 20, 26, .20));
  border: 2px solid var(--sg-orange, #FF6D00);
  -webkit-backdrop-filter: var(--sg-row-blur, blur(8px));
  backdrop-filter: var(--sg-row-blur, blur(8px));
  box-shadow: 0 0 8px rgba(255, 109, 0, .35);
  opacity: 1;
  /* Decorative. Without this the disc would swallow taps on whatever sits
     beneath the top-left corner of every screen. */
  pointer-events: none;
  z-index: 9500;
}

/* The per-card copies are retired in favour of the single fixed mark above.
   Hidden rather than deleted from the shells so the markup that generates a
   reel card stays untouched and this stays one reversible decision. */
.sg-brand-circle {
  display: none !important;
}


/* ── talk-bar.css ── */
/* ═══════════════════════════════════════════════════════════════════════════
   talk-bar.css — the one call to action, as a bar across the bottom.

   The product promise is that you say what you want and it happens. A 71x46
   pill tucked in the bottom-right corner does not read as the main way to use
   the app; it reads as a help widget. This makes it the widest, most obvious
   thing on the screen.

   ── Why this file sets no `bottom` ──────────────────────────────────────────
   Each tab's script already positions its own pill with an inline
   `style="bottom: Npx !important"`, and the values are per-tab and correct:

       Reels 69   Book 102   ScanSquad 69   Partner 68   Profile 68

   Book is higher because it alone has #sg-book-summary ("Today · Day Pass ·
   £4.49"), a 26px fixed strip above the tab bar. That arithmetic is already
   right, and an inline !important cannot be overridden from a stylesheet
   anyway. So this file changes shape only and inherits the vertical position.
   If you ever need to move it, change the JS that writes the inline style —
   editing `bottom` here will silently do nothing.

   ── The 52px gap on Book ────────────────────────────────────────────────────
   The gym card ends at y710 and the summary strip starts at y762, leaving 52px
   of bare page background in the middle of the thumb zone — measured with
   elementFromPoint, which returns #app all the way through it. The bar lands in
   that gap. It is a genuine fix for wasted space, not a cover-up: the gap is a
   sizing bug in the card and is tracked separately.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Why every selector carries `.show` ─────────────────────────────────────
   All five pills exist in the DOM of the single-page app at once. chat-agent.js
   keeps them at `display:none` and adds `.show` to the one belonging to the
   current tab. The first draft of this file styled the bare ids and included
   `display:flex !important`, which overrode that and put FIVE full-width Talk
   bars on Book, Partner and Profile simultaneously — the exact regression
   one-cta.css warns about in its header. Rendering the tabs caught it; the unit
   tests were all green.

   So: never set `display` here, and only ever match the shown pill. */
#rchat-fab.show,
#bchat-fab.show,
#schat-fab.show,
#pchat-fab.show,
#mchat-fab.show {
  /* Full width, inset a little so it reads as a control rather than a slab. */
  left: 12px !important;
  right: 12px !important;
  width: auto !important;
  min-width: 0 !important;
  max-width: none !important;

  height: 52px !important;
  padding: 0 20px !important;
  border-radius: 14px !important;

  align-items: center !important;
  justify-content: center !important;
  gap: 10px !important;

  font-size: 17px !important;
  font-weight: 800 !important;
  letter-spacing: .2px !important;

  /* Lifts the bar off the content behind it without adding a second colour. */
  box-shadow: 0 -6px 24px rgba(0, 0, 0, .45),
              0 0 0 1px rgba(255, 255, 255, .08) inset !important;
}


/* ── book-by-tap.css ── */
/* ═══════════════════════════════════════════════════════════════════════════
   book-by-tap.css — the purchase is a button again.

   WHY
   one-cta.css made the Talk pill the only call to action on every tab and, as
   its own header says, "#sg-continue-banner carries the *purchase* action on
   Book, so this file is where booking-by-tap went". A first-customer test on
   8 Sep 2026 showed what that costs: a visitor on the Book tab tapped the card,
   the gym name and the price strip, none of which book, and never found the
   "Day" icon in the right rail that does. The only orange thing on the screen
   said "Talk". People who will not speak to a website did not pay.

   THE RULE
   Talk stays on every tab. But when the app has a concrete thing to sell —
   the continue banner is active (body.sg-cb-active, set by app.ctr576.js on
   Reels and Book) — that bar is the primary action and is painted brand orange;
   the Talk bar steps back to a compact pill on the right. ScanSquad's form gets
   its submit button back, because a form you cannot submit is a dead end.

   Loaded last, after one-cta.css / one-orange.css / talk-bar.css, so it wins
   on order alone. Deleting this file restores the voice-only surface exactly.
   ═══════════════════════════════════════════════════════════════════════════ */

/* The purchase bar: visible and orange while it has something to sell. */
body.sg-cb-active #sg-continue-banner {
  display: flex !important;
  background: linear-gradient(135deg, #FF6D00 0%, #E66200 100%) !important;
  background-image: linear-gradient(135deg, #FF6D00 0%, #E66200 100%) !important;
  box-shadow: 0 -4px 20px rgba(255, 109, 0, .25) !important;
}
body.sg-cb-active #sg-continue-banner .sg-cb-text,
body.sg-cb-active #sg-continue-banner .sg-cb-arrow {
  color: #fff !important;
}
body.sg-cb-active #sg-continue-banner .sg-cb-price {
  color: rgba(255, 255, 255, .8) !important;
}

/* Talk steps back to a pill while the purchase bar is showing. Same element,
   same handler — only its shape changes. `bottom` is left alone on purpose:
   sg-dock.js writes it inline so the pill clears the stacked bars. */
body.sg-cb-active #bchat-fab.show,
body.sg-cb-active #rchat-fab.show,
body.sg-cb-active #schat-fab.show,
body.sg-cb-active #pchat-fab.show,
body.sg-cb-active #mchat-fab.show {
  left: auto !important;
  right: 12px !important;
  width: auto !important;
  height: 42px !important;
  padding: 0 16px 0 13px !important;
  border-radius: 21px !important;
  font-size: 14px !important;
  box-shadow: 0 8px 28px rgba(255, 109, 0, .45) !important;
}

/* ScanSquad: the join form's own submit button. */
#join-btn {
  display: inline-flex !important;
}

/* ScanSquad is its own page (no continue banner, so no body.sg-cb-active) and the
   full-width Talk bar sat exactly on top of the form's "Start Earning" button.
   Talk stays; it is a pill here so the form can be submitted. */
#schat-fab.show {
  left: auto !important;
  right: 12px !important;
  width: auto !important;
  height: 42px !important;
  padding: 0 16px 0 13px !important;
  border-radius: 21px !important;
  font-size: 14px !important;
}

/* The Reels tab embeds /reels/ in an iframe. The framed page has its own Talk bar
   and the shell around it has a Talk pill *and* the "Book in London →" bar, so the
   screen showed two Talk buttons. reels/index.html adds .sg-framed to <html> when
   it is inside the shell; the framed copy of Talk then steps aside. Opening /reels/
   directly (no frame) keeps its bar. */
html.sg-framed #rchat-fab.show {
  display: none !important;
}

/* Straight after paying, the confirmation page still carried "Book this gym · £4.49 →"
   at the bottom — an invitation to buy the same pass twice. render() stamps the route
   on <body>; on the success page the bar steps aside and Talk returns to full width. */
body[data-route="/booking-success"] #sg-continue-banner { display: none !important; }
body[data-route="/booking-success"].sg-cb-active #bchat-fab.show,
body[data-route="/booking-success"].sg-cb-active #chat-fab.show {
  left: 12px !important; right: 12px !important; width: auto !important;
}


/* ── rails.css ── */
/* ═══════════════════════════════════════════════════════════════════════════
   rails.css — the ONE place that decides where the app's action buttons live.

   History, because it explains every rule below.

   The buttons used to be a vertical rail on the right edge of each card. It was
   measured on production (390×844, Book tab, "More" expanded) and it was broken
   in two ways at once:

     rail of card 1 ... y197 → y741, with "4.4 (136)" at y665 under the Talk
                        pill, "Share" y728 under the page, "Earn"/"Filter" off
                        the bottom of the screen entirely
     rail of card 2 ... y775, a SECOND identical column, half behind the tab bar

   Fixing that took reserving the bottom furniture (tab bar 56 + Talk pill 46+12
   + summary 26 + CTA 52) and letting only the on-screen card keep its rail —
   the rails sit at z-index 25/8990/8998 while the orange CTA is 10001, so
   raising them would only have hidden the CTA. Geometry, not layering.

   The owner then chose a different shape: one horizontal row that side-scrolls,
   above the bottom navigation, in the white style Reels and Book already use,
   with each tab keeping its own buttons. That row is defined below, and the
   reasoning about the bottom furniture carries straight over — it is what
   decides how high the row has to sit.

   If you need to move a row, change it HERE. A second opinion in another file
   is what produced the overlap in the first place, and tests/one-right-rail
   enforces that this file stays the only one with an opinion.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Only the card you are looking at owns the row ─────────────────────────
   Every card carries its own rail, and with the row fixed to the screen they
   would stack on the same 72px. rails.js marks the dominant card
   `sg-card-live`; until it has run nothing is hidden, because a row you cannot
   see is worse than one row too many. */
.tt-view.sg-rails-arbitrated .tt-card:not(.sg-card-live) .tt-actions {
  display: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE BAND (owner's call, 2026-09-17; position corrected 2026-09-18)

   The buttons move off the right edge and become ONE horizontal row that
   side-scrolls, in the same white style Reels and Book already use. Each tab
   keeps its own buttons — this file only decides where the row lives and how
   it behaves, never what is in it.

   WHERE, exactly (owner, 2026-09-18): "Between bottom navigation and Ask AI
   orange CTA button". Stacking from the bottom of the screen upwards:

     tab bar ......... nav, 56px on production
     ── THE ROW ──     here
     orange CTA ...... "Book this gym" / "Ask AI"
     price summary ... the line that explains the CTA
     Talk pill ....... floats above the whole stack

   An earlier pass put the row ABOVE the CTA and the pill, on the reasoning
   that the pill sat in this gap and would cover the row's last buttons. That
   was true of the old vertical rail, which nothing docked. It is not true now:
   sg-dock.js owns the bottom edge, and it has been taught to count the row as
   the first thing above the nav — so the CTA, the summary and the pill all
   stack ON TOP of the row and cannot reach it. The gap is the row's.

   That is also why this file no longer hardcodes 174px. The dock measures the
   nav and publishes `--sg-nav-h` / `--sg-safe-b`; the row is defined in terms
   of those, so a taller nav or a device with a home bar moves the row with it
   instead of leaving it floating or buried.

   Because it scrolls sideways, nothing has to hide any more: the "More"
   collapse the vertical rail needed is switched off here, so every button is
   reachable by swiping the row. rails.js adds `sg-rail-scrollable` when there
   is more to the right, and the arrow below is that indication.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Height of the row itself (44px circle + 11px label + breathing room). */
  --sg-band-height: 72px;
  /* Breathing room between the nav and the row. */
  --sg-band-gap: 4px;
  /* The row sits directly above the bottom navigation. sg-dock.js measures the
     nav every pass and publishes these; the fallbacks are production's numbers
     for the frame before the dock's first pass. */
  --sg-band-bottom: calc(var(--sg-nav-h, 56px) + var(--sg-safe-b, 0px) + var(--sg-band-gap));
  /* A .tt-card lives inside .tt-view, which already stops above the nav, so a
     card rail must not reserve it — or its safe area — twice. */
  --sg-band-bottom-card: var(--sg-band-gap);
  --sg-band-pad: 12px;
}

/* ── WHERE THE ROW SITS (fixed 2026-09-17, second pass) ───────────────────
   The first pass made every row `position: fixed`. On Book and Partner that
   put the row in the MIDDLE of the photo instead of above the CTA, and the
   cause is not the carousel's transform but containment: app.ctr576.js ships
   `.tt-card{contain:layout style paint}` and `.tt-carousel{contain:strict}`,
   and a contained element is a containing block for its fixed descendants.
   So `bottom: 174px` was measured from the bottom of the CARD, which is
   min-height:100% of a scroll-snap strip, not from the screen.

   Fixing it by removing containment would hand back the paint budget those
   two rules were added for. So each row is pinned to the bottom of whatever
   is genuinely full-screen:

     .tt-actions   card rails       absolute inside .tt-card — the card fills
                                    .tt-view, which already stops above the
                                    nav, so it only needs the gap
     .reel-actions reel slides      absolute inside .reel, a full 100dvh slide
     the three floating rails       body-level, so fixed and clearing the nav

   Every one of them still reads the SAME band variables; only the reference
   frame differs, and that is the whole reason this file exists.
   ───────────────────────────────────────────────────────────────────────── */

.tt-actions,
.reel-actions,
#sg-reels-rail,
#sg-sv-rail.sv-float,
#sg-profile-rail,
.sg-pr-host-capped {
  left: 0 !important;
  right: 0 !important;
  top: auto !important;
  height: var(--sg-band-height) !important;
  max-height: var(--sg-band-height) !important;
  flex-direction: row !important;
  align-items: center !important;
  justify-content: flex-start !important;
  gap: 14px !important;
  padding: 0 var(--sg-band-pad) !important;
  overflow-x: auto !important;
  overflow-y: hidden !important;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
  z-index: 26;
  /* Fade the right edge so a half-cut button reads as "there is more". */
  -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 34px), transparent 100%);
  mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 34px), transparent 100%);
}

/* Body-level rails: fixed, clearing the whole stack. */
#sg-reels-rail,
#sg-sv-rail.sv-float,
#sg-profile-rail,
.sg-pr-host-capped {
  position: fixed !important;
  bottom: var(--sg-band-bottom) !important;
}

/* ── Profile has TWO rails, and only one of them was ever styled ───────────
   profile-rail.js floats `#sg-profile-rail` only when the app has no rail of
   its own; when the app DOES render one, it extends that native rail instead
   and marks it `sg-pr-host-capped`. That host is the app's own element, so
   none of the rules above reached it: measured on production 2026-09-18,
   Profile was a VERTICAL column at x330-380, y92-696 (Sign Up, Find Gym,
   Pricing, Creator, Help, Connect, Telegram) while every other tab had the
   row. Which rail you get depends on app state, so the tab looked fixed in
   one check and unfixed in the next.
   The host joins the band on the same terms as the others. Its own
   `max-height: calc(100vh - 240px)` and `overflow-y: auto` are what made it a
   tall scrolling column, so both are overridden here. */
/* `html body` because profile-rail.js injects its own
   `.sg-pr-host-capped{overflow-y:auto!important}` from a <style> appended at
   init — later in the document, so with equal specificity it wins. Measured
   2026-09-18: max-height applied, overflow-y did not. */
html body .sg-pr-host-capped {
  max-height: var(--sg-band-height) !important;
  overflow-y: hidden !important;
  padding: 0 var(--sg-band-pad) !important;
  margin: 0 !important;
}
/* The column stacked its children vertically with a wrapper in the middle. */
.sg-pr-host-capped #sg-profile-rail-ext {
  flex-direction: row !important;
  align-items: center !important;
  gap: 14px !important;
  margin-top: 0 !important;
}

/* Card and reel rails: absolute, pinned to the bottom of their full-screen
   parent. Same band, measured from the right edge of the world. */
.tt-actions {
  position: absolute !important;
  bottom: var(--sg-band-bottom-card) !important;
}
.reel-actions {
  position: absolute !important;
  bottom: var(--sg-band-bottom) !important;
}

.tt-actions::-webkit-scrollbar,
.reel-actions::-webkit-scrollbar,
#sg-reels-rail::-webkit-scrollbar,
#sg-sv-rail.sv-float::-webkit-scrollbar,
#sg-profile-rail::-webkit-scrollbar,
.sg-pr-host-capped::-webkit-scrollbar { display: none; }

/* A row that is fully visible should not be faded or arrowed. */
.tt-actions:not(.sg-rail-scrollable),
.reel-actions:not(.sg-rail-scrollable),
#sg-reels-rail:not(.sg-rail-scrollable),
#sg-sv-rail.sv-float:not(.sg-rail-scrollable),
#sg-profile-rail:not(.sg-rail-scrollable),
.sg-pr-host-capped:not(.sg-rail-scrollable) {
  -webkit-mask-image: none;
  mask-image: none;
}

.tt-actions > *,
.reel-actions > *,
#sg-reels-rail > *,
#sg-sv-rail.sv-float > *,
#sg-profile-rail > *,
.sg-pr-host-capped > *,
.sg-pr-host-capped #sg-profile-rail-ext > * {
  flex: 0 0 auto;
  scroll-snap-align: start;
}

/* Sideways scrolling makes hiding pointless: show every button, drop "More". */
.tt-actions .tt-action.sgi-x { display: flex !important; }
.tt-actions .tt-action.sgi-more { display: none !important; }

/* The indication: an arrow pinned to the right edge of a row that has more.
   `position: sticky` keeps it in place while the row scrolls under it, and it
   disappears once the end is reached (the class is re-evaluated on scroll). */
.sg-rail-scrollable::after {
  content: '›';
  position: sticky;
  right: 0;
  flex: 0 0 auto;
  align-self: center;
  font-size: 22px;
  line-height: 1;
  padding: 0 2px 0 6px;
  color: rgba(255, 255, 255, .75);
  text-shadow: 0 1px 4px rgba(0, 0, 0, .9);
  pointer-events: none;
}

/* The same arrow on the LEFT once the row has been scrolled (owner,
   2026-09-30: "arrow only right side not left side"). Pulled out of the flow
   with a negative margin so it appearing never shifts the buttons. Both arrows
   are tappable: rails.js pages the row when a tap lands on either edge. */
.tt-actions.sg-rail-scroll-left::before,
.sg-rail-scroll-left::before {
  content: '\2039';
  position: sticky;
  left: 0;
  z-index: 3;
  flex: 0 0 auto;
  align-self: center;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-right: -22px;
  font-size: 22px;
  line-height: 1;
  color: rgba(255, 255, 255, .75);
  background: rgba(13, 16, 25, .62);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 50%;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .9);
  pointer-events: none;
}

/* ── No half-built rail on screen ──────────────────────────────────────────
   A gym card renders with the app's raw rail: emoji icons, every item
   expanded. sg-rail-ui.js turns that into the white 4 + More rail and stamps
   it `data-sgi`. Until it does, the raw version is a second, different-looking
   column of the same buttons — what the owner saw as "white button and emoji
   button on the right side".

   So: while sg-rail-ui.js is confirmed alive (`sg-rail-ui-ready` on <html>,
   set only after it has decorated a rail), an undecorated rail stays
   invisible. It is still laid out and measurable — only unpainted — so nothing
   jumps when it is decorated a frame later. If that script never runs, this
   rule never applies and the raw rail shows as before. */
.sg-rail-ui-ready .tt-actions:not([data-sgi]) {
  opacity: 0;
  pointer-events: none;
}
.tt-actions[data-sgi] {
  transition: opacity .04s linear;
}

/* ── The white the owner asked for ────────────────────────────────────────
   "Same white colour like reels and book tab buttons." Reels labels are solid
   #fff with a shadow; the card rails were rgba(255,255,255,.7) at 9px, which
   over a bright gym photo read as grey (measured on the Partner tab: the row
   was barely legible). One white, one shadow, everywhere. */
.tt-actions .tt-action-label,
.reel-actions .label,
#sg-reels-rail .sg-rr-label,
#sg-profile-rail .sg-rr-label,
.sg-pr-host-capped .sg-pr-label {
  color: #fff !important;
  font-size: 10px !important;
  font-weight: 600 !important;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .85) !important;
}
.tt-actions .tt-action-btn,
.reel-actions .icon {
  opacity: 1 !important;
  color: #fff !important;
}

/* The row reads over any photo without darkening the picture itself. */
.tt-actions::before { content: none; }
.tt-actions,
.reel-actions,
#sg-reels-rail,
#sg-sv-rail.sv-float,
#sg-profile-rail,
.sg-pr-host-capped {
  background: linear-gradient(to top, rgba(0, 0, 0, .34), rgba(0, 0, 0, 0));
}

/* A clearer "there is more than fits" than a lone chevron: the arrow sits in a
   small dark disc, so it is visible on a white-lit photo too. */
.sg-rail-scrollable::after {
  background: rgba(13, 16, 25, .62);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 50%;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  padding: 0 0 2px 0;
}

/* ── The card tabs have to reach the nav, or the row cannot sit above it ──────
   Book and Partner draw their row INSIDE the card (`.tt-card` has
   `contain: content`, so a fixed child is impossible and anything sticking out
   is clipped). The card is as tall as `main.sg-tab-content`, and sg-rail-ui.js
   ends that container 134px above the bottom — room it reserves for the CTA and
   the price summary. Result on 2026-09-18: the row rendered 4px above the CARD,
   at y660–732, while the CTA sat at y656–708 and covered its icons; only the
   labels showed below it. Measured on production, 390×844.
   So the container owns the nav's edge and nothing else. The CTA, the summary
   and the Talk pill are `fixed`: sg-dock.js already stacks them above the
   reserved row, and they float over the photo the way they do on Reels.
   The class is repeated to win on specificity: sg-rail-ui.js injects
   `body.sg-r4-summary.sg-cb-active .sg-tab-content!important` (three classes),
   which is why the first attempt fixed Partner but not Book — Book is the tab
   that carries both body classes. Four classes here beats it, and because both
   are !important the later-injected sheet no longer decides. --sg-nav-h is 0 when the nav is hidden, so
   a full-bleed state still gets the whole viewport. */
/* Task 11 (owner, 2026-10-04): "every tab is transparent or see through so we
   have full screen videos and photos". A tab that STOPS above the nav can never
   show a photo behind it, however transparent the bar is, so every tab surface
   now reaches the bottom of the screen and reserves the nav as padding instead
   of as a missing 56px. sg-dock.js already sets a larger inline padding-bottom
   (nav + row + pills) whenever the tab actually scrolls; this is the floor for
   the frames before its first pass and for tabs that do not scroll. */
html body main.sg-tab-content.sg-tab-content.sg-tab-content.sg-tab-content {
  bottom: 0 !important;
  padding-bottom: calc(var(--sg-nav-h, 56px) + var(--sg-safe-b, 0px));
}

/* ── The Reels tab is an iframe, and it has to reach the nav too ────────────
   /reels is its own document; the SPA shows it in `.sg-reels-frame`. The frame
   is sized by app.ctr576.js, which ends it above the orange CTA
   (`body.sg-cb-active .sg-reels-frame{bottom:calc(56px+52px+safe)!important}`).
   The row inside the frame is pinned to the frame's bottom, so the order came
   out nav → CTA → row: measured on production 2026-09-18, row y660–730 with
   the CTA below it at y736–788. The owner wants the row directly above the nav
   on every tab.
   So the frame owns the nav's edge, exactly like the card tabs, and the CTA
   floats over it — sg-dock.js reserves the band for the frame because it
   cannot measure into another document. Three classes to beat the injected
   `body.sg-cb-active .sg-reels-frame !important`.
   Task 11 (owner, 2026-10-04): the frame no longer stops at the nav either — it
   is the full viewport, so the reel plays behind the see-through tab bar. The
   row inside the frame still clears the bar: sg-dock.js reserves the parent's
   nav height when it finds itself in a frame with no nav of its own. */
html body .sg-reels-frame.sg-reels-frame.sg-reels-frame {
  bottom: 0 !important;
  height: 100dvh !important;
}

/* The SPA's live path is not that one. It keeps a persistent wrapper,
   `#sg-reels-persistent`, which ALREADY ends at the nav (measured: 0→788), and
   puts `#sg-reels-iframe` inside it — but app.ctr576.js shortens the iframe to
   `calc(100vh - 56px - 52px - safe)` = 736px whenever the CTA is up. So the
   frame stopped 52px short of its own wrapper and the row went with it: row
   y660–732, CTA y656–708 on top of it. The iframe fills its wrapper instead;
   the wrapper is the thing that knows about the nav.
   The id is written twice on purpose: the injected rule is
   `body.sg-cb-active #sg-reels-iframe` — one id AND a class — so a single id
   here loses and the first attempt (v1.6) changed nothing on screen. */
html body #sg-reels-iframe#sg-reels-iframe {
  top: 0 !important;
  bottom: 0 !important;
  height: 100% !important;
}

/* Task 11 (owner, 2026-10-04): and the wrapper itself reaches the bottom, so
   the reel plays behind the see-through tab bar instead of ending above it.
   `_ensureReelsIframe()` writes `bottom:calc(56px + safe)` as an INLINE style,
   which only !important can beat. */
html body #sg-reels-persistent#sg-reels-persistent {
  bottom: 0 !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
   THE ORANGE CTA JOINS THE ROW (owner's call, 2026-09-18, second decision)

   Until now the bottom of the screen had three layers: nav 56 + row 72 + the
   full-width orange bar 52, plus the price summary and the Talk pill floating
   over them — 188px of chrome before any content. The owner asked for the
   orange CTA to move INTO the row with the other buttons, one strip per tab.

   It stays the SAME element, `#sg-continue-banner`. Everything that makes it
   work — the tap handler, the checkout flow, the per-tab label ("Book this gym
   · £5.49", "Find gyms near me", "Start Earning", "Continue"), the loading
   spinner sg-rail-ui.js puts in it — is bound to that id, so re-parenting or
   rebuilding it would mean re-testing checkout on every tab. Instead it is
   restyled into a pill and parked at the left end of the band, where a row's
   first item would be, and the rows are given a left inset so their circles
   start after it. Same pixels as a real first item, none of the risk.

   `sg-cta-in-row` is set by rails.js, not hardcoded here, so the whole change
   can be turned off from one line if the booking rate dips.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* The pill matches the white circles' 44px so the row reads as one strip. */
  --sg-cta-h: 44px;
  /* Published by rails.js once the pill has been measured; the rows read it to
     know how far in to start. 0 until then, which is the old full-width look
     for one frame rather than a gap where the buttons should be. */
  --sg-cta-w: 0px;
}

/* The id twice, for the same reason as the Reels iframe above: sg-dock.js and
   app-patches.js both write `#sg-continue-banner` rules, and the dock also
   sets an inline `bottom` — it is taught to leave this element alone while the
   class is on (see sg-dock.js), but the specificity still has to hold. */
html body.sg-cta-in-row #sg-continue-banner#sg-continue-banner {
  left: var(--sg-band-pad) !important;
  right: auto !important;
  width: auto !important;
  /* Measured 2026-09-18: with no cap, "Ask AI \"How much have I made this
     week\"" made the pill 293px of a 390px screen on Partner and 312px on
     Profile, leaving one clipped circle and nothing to swipe. The pill takes
     at most 58% and the label ellipsises; the row keeps the rest. */
  max-width: 58% !important;
  overflow: hidden !important;
  height: var(--sg-cta-h) !important;
  /* Centred in the band, so the pill and the circles share a midline. */
  bottom: calc(var(--sg-band-bottom) + (var(--sg-band-height) - var(--sg-cta-h)) / 2) !important;
  padding: 0 18px !important;
  border-radius: calc(var(--sg-cta-h) / 2) !important;
  box-shadow: 0 2px 14px rgba(0, 0, 0, .45) !important;
  /* A pill over a photo needs its own edge; the full-width bar never did. */
  border: 1px solid rgba(255, 255, 255, .16) !important;
}

/* 16px was sized for a full-width bar. In a pill it pushes "Book this gym ·
   £5.49" wider than half the screen and leaves no room to swipe the row. */
/* Measured 2026-09-18: capping the pill made flexbox shrink the FIRST child,
   so "Ask AI" rendered as "As..." and "Continue" as "Co...". The primary word
   is the whole point of the button, so it never shrinks; the quoted sub-label
   ("How much have I made this week") is what gives way. */
body.sg-cta-in-row #sg-continue-banner .sg-cb-text {
  font-size: 14px !important;
  white-space: nowrap !important;
  flex: 0 0 auto !important;
}
body.sg-cta-in-row #sg-continue-banner .sg-cb-sub {
  flex: 1 1 auto !important;
  min-width: 0 !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
body.sg-cta-in-row #sg-continue-banner .sg-cb-price {
  font-size: 12px !important;
  white-space: nowrap !important;
}


/* The rows start after the pill. Later than the `padding: 0 var(--sg-band-pad)`
   rule above and equally !important, so this wins without another class. */
/* MARGIN, not padding. Padding lives INSIDE the scroller, so the moment
   anything scrolls the row (sg-rail-ui scrolls the active chip into view, and
   these rows overflow by design) the padding scrolls away with it and the
   first buttons slide UNDER the fixed pills: measured on Book with
   padding-left 124px and scrollLeft 124, "Near Me" sat at x0-44 beneath a
   button at x12-54. A margin shortens the scroller itself, so there is no
   space under the pills for content to reach. */
body.sg-cta-in-row .tt-actions,
body.sg-cta-in-row .reel-actions,
body.sg-cta-in-row #sg-reels-rail,
body.sg-cta-in-row #sg-sv-rail.sv-float,
body.sg-cta-in-row #sg-profile-rail,
body.sg-cta-in-row .sg-pr-host-capped {
  margin-left: calc(var(--sg-cta-w) + var(--sg-band-pad) + 14px) !important;
  padding-left: var(--sg-band-pad) !important;
}

/* Inside the Reels iframe the pill is in the PARENT document and cannot be
   measured, so rails.js posts its width across and the framed copy of this
   file applies the same inset. Nothing else about the row changes. */


/* ═══════════════════════════════════════════════════════════════════════════
   ONE ROW, ONE STYLE (owner, 2026-09-18, third decision)

   "No orange button — looks same like other white button in row", and the
   floating Talk pill joins the row too. After this there is nothing floating
   over the content: the whole bottom is nav + one strip.

   The buttons keep their ids and handlers for the same reason as before —
   `#sg-continue-banner` owns checkout, and each tab's Talk pill
   (#bchat-fab … #chat-fab, one per chat personality) owns the voice agent.
   Only their looks and their place change.
   ═══════════════════════════════════════════════════════════════════════════ */

/* The main button loses the orange and takes the row's glass-circle look:
   same background, border, blur and shadow as .sg-pr-circle / .tt-action-btn. */
html body.sg-cta-in-row #sg-continue-banner#sg-continue-banner {
  background: rgba(0, 0, 0, .4) !important;
  border: 1px solid rgba(255, 255, 255, .12) !important;
  -webkit-backdrop-filter: blur(12px) !important;
  backdrop-filter: blur(12px) !important;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .25) !important;
}

/* The Talk pill sits next in the row, after the main button. rails.js
   publishes where that is, because the main button's width changes with its
   label. Its own sheet pins it `right: 14px; z-index: 9100`, so both are
   overridden here. */
/* Each id twice. book-by-tap.css pins the pill with
   `body.sg-cb-active #bchat-fab.show{left:auto!important;right:12px!important}`
   — id + TWO classes — so the first attempt (v2.2) recoloured the pill but
   left it at the right edge, sitting on top of the row's buttons: measured
   Talk at x301-378 over the first button at x335-379. Two ids beat it. */
body.sg-cta-in-row #bchat-fab#bchat-fab,
body.sg-cta-in-row #pchat-fab#pchat-fab,
body.sg-cta-in-row #schat-fab#schat-fab,
body.sg-cta-in-row #rchat-fab#rchat-fab,
body.sg-cta-in-row #mchat-fab#mchat-fab,
body.sg-cta-in-row #chat-fab#chat-fab {
  position: fixed !important;
  left: var(--sg-talk-left, 12px) !important;
  right: auto !important;
  bottom: calc(var(--sg-band-bottom) + (var(--sg-band-height) - var(--sg-cta-h)) / 2) !important;
  height: var(--sg-cta-h) !important;
  padding: 0 14px !important;
  border-radius: calc(var(--sg-cta-h) / 2) !important;
  background: rgba(0, 0, 0, .4) !important;
  border: 1px solid rgba(255, 255, 255, .12) !important;
  -webkit-backdrop-filter: blur(12px) !important;
  backdrop-filter: blur(12px) !important;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .25) !important;
  color: #fff !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  /* Above the row's own scroll strip, below the nav. */
  z-index: 27 !important;
  animation: none !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
   ONE ROW, ONE SHAPE (owner, 2026-09-18, fourth decision — chose option A)

   "Yes but this are not same size or same looking like other buttons in same
   row." Correct: v2.3 gave both pills the row's colour but not its shape —
   the main button measured 218px wide and Talk 74px, next to 42px circles
   with a 10px label under them.

   So the main button and Talk become that same icon-and-label item. The words
   go: "Book this gym · £5.00" becomes a 💳 circle labelled "Book". The owner
   was told the price and the Ask AI prompt stop showing on screen and chose
   this over keeping the text, because it also frees ~250px — every button in
   the row now fits without the chevron.

   Ids and handlers are untouched, as before: only looks and place change.
   Revert = drop CTA_IN_ROW in rails.js.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* The row's own metrics, read off .tt-action-btn.sgi in sg-rail-ui.js and
     the measured live rects: circle 42px, 10px label 3px under it. --sg-row-
     lift is the gap from the band's bottom to the circle's bottom, so both
     new items line up with the buttons already in the row. */
  /* 44px, not the measured 42px: at 42 the Gyms / Talk / Sign in circles were
     the only controls in the app under the 44px minimum tap target. */
  --sg-row-ico: 44px;
  --sg-row-cap: 12px;
  --sg-row-lift: 23px;
}

/* The main button is now a column: circle on top, label under. Its own box
   carries nothing visible — the circle inside it does — so the glass look set
   by the third decision above is switched back off here. */
html body.sg-cta-in-row #sg-continue-banner#sg-continue-banner {
  left: var(--sg-band-pad) !important;
  right: auto !important;
  width: auto !important;
  min-width: 0 !important;
  max-width: none !important;
  height: auto !important;
  bottom: calc(var(--sg-band-bottom) + var(--sg-row-lift) - var(--sg-row-cap) - 3px) !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: flex-end !important;
  gap: 3px !important;
  padding: 0 !important;
  background: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* The label text the button used to show is what made it 218px wide. */
html body.sg-cta-in-row #sg-continue-banner .sg-cb-text,
html body.sg-cta-in-row #sg-continue-banner .sg-cb-sub,
html body.sg-cta-in-row #sg-continue-banner .sg-cb-price,
html body.sg-cta-in-row #sg-continue-banner .sg-cb-arrow {
  display: none !important;
}

/* rails.js puts these two in: the glyph and the short caption. */
html body.sg-cta-in-row #sg-continue-banner .sg-cb-ico {
  display: flex !important;
  align-items: center;
  justify-content: center;
  width: var(--sg-row-ico) !important;
  height: var(--sg-row-ico) !important;
  border-radius: 50% !important;
  /* one-button.css owns the look of every circle in this row; this one used to
     carry its own darker glass and a thinner border. */
  background: var(--sg-btn-bg, rgba(255, 255, 255, .07)) !important;
  border: var(--sg-btn-border-width, 1px) solid var(--sg-btn-border-color, rgba(255, 255, 255, .16)) !important;
  -webkit-backdrop-filter: var(--sg-btn-blur, blur(8px));
  backdrop-filter: var(--sg-btn-blur, blur(8px));
  box-shadow: var(--sg-btn-shadow, 0 2px 10px rgba(0, 0, 0, .25)) !important;
  font-size: var(--sg-btn-icon, 20px) !important;
  color: #fff !important;
  line-height: 1 !important;
}
html body.sg-cta-in-row #sg-continue-banner .sg-cb-ico svg {
  width: var(--sg-btn-icon, 20px) !important;
  height: var(--sg-btn-icon, 20px) !important;
  display: block;
}
html body.sg-cta-in-row #sg-continue-banner .sg-cb-cap {
  display: block !important;
  color: var(--sg-btn-label-color, #fff) !important;
  font-size: var(--sg-btn-label-size, 10px) !important;
  font-weight: var(--sg-btn-label-weight, 600) !important;
  line-height: var(--sg-row-cap) !important;
  letter-spacing: 0 !important;
  white-space: nowrap !important;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .85) !important;
}

/* Talk, same treatment. Its text is a bare node inside the button, not an
   element, so it cannot be hidden with a selector: `font-size: 0` collapses
   it and the glyph and caption come from pseudo-elements. Each id twice, for
   the book-by-tap.css reason noted above. */
body.sg-cta-in-row #bchat-fab#bchat-fab,
body.sg-cta-in-row #pchat-fab#pchat-fab,
body.sg-cta-in-row #schat-fab#schat-fab,
body.sg-cta-in-row #rchat-fab#rchat-fab,
body.sg-cta-in-row #mchat-fab#mchat-fab,
body.sg-cta-in-row #chat-fab#chat-fab {
  left: var(--sg-talk-left, 12px) !important;
  bottom: calc(var(--sg-band-bottom) + var(--sg-row-lift)) !important;
  width: var(--sg-row-ico) !important;
  min-width: 0 !important;
  height: var(--sg-row-ico) !important;
  padding: 0 !important;
  border-radius: 50% !important;
  background: var(--sg-btn-bg, rgba(255, 255, 255, .07)) !important;
  border: var(--sg-btn-border-width, 1px) solid var(--sg-btn-border-color, rgba(255, 255, 255, .16)) !important;
  -webkit-backdrop-filter: var(--sg-btn-blur, blur(8px)) !important;
  backdrop-filter: var(--sg-btn-blur, blur(8px)) !important;
  box-shadow: var(--sg-btn-shadow, 0 2px 10px rgba(0, 0, 0, .25)) !important;
  font-size: 0 !important;
  overflow: visible !important;
}
body.sg-cta-in-row #bchat-fab#bchat-fab > *,
body.sg-cta-in-row #pchat-fab#pchat-fab > *,
body.sg-cta-in-row #schat-fab#schat-fab > *,
body.sg-cta-in-row #rchat-fab#rchat-fab > *,
body.sg-cta-in-row #mchat-fab#mchat-fab > *,
body.sg-cta-in-row #chat-fab#chat-fab > * {
  display: none !important;
}
body.sg-cta-in-row #bchat-fab#bchat-fab::before,
body.sg-cta-in-row #pchat-fab#pchat-fab::before,
body.sg-cta-in-row #schat-fab#schat-fab::before,
body.sg-cta-in-row #rchat-fab#rchat-fab::before,
body.sg-cta-in-row #mchat-fab#mchat-fab::before,
body.sg-cta-in-row #chat-fab#chat-fab::before {
  content: '\1F3A4' !important;
  font-size: 19px !important;
  line-height: 1 !important;
}
body.sg-cta-in-row #bchat-fab#bchat-fab::after,
body.sg-cta-in-row #pchat-fab#pchat-fab::after,
body.sg-cta-in-row #schat-fab#schat-fab::after,
body.sg-cta-in-row #rchat-fab#rchat-fab::after,
body.sg-cta-in-row #mchat-fab#mchat-fab::after,
body.sg-cta-in-row #chat-fab#chat-fab::after {
  content: 'Talk' !important;
  position: absolute !important;
  top: calc(100% + 3px) !important;
  left: 50% !important;
  transform: translateX(-50%) !important;
  color: var(--sg-btn-label-color, #fff) !important;
  font-size: var(--sg-btn-label-size, 10px) !important;
  font-weight: var(--sg-btn-label-weight, 600) !important;
  line-height: var(--sg-row-cap) !important;
  white-space: nowrap !important;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .85) !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
   THE PILLS ARE IN THE ROW (owner, 2026-09-18, fourth decision)

   "These buttons are not moved in with other scrolling buttons." rails.js now
   moves the main button and the Talk pill into `.sg-row-slot`, the first item
   of the row's own scroller, so they scroll and clip with every other button.
   Everything below undoes the fixed positioning those elements carry from
   sg-dock.js / book-by-tap.css / the parked rules above, which still apply
   whenever `sg-cta-rides-row` is absent.
   ═══════════════════════════════════════════════════════════════════════════ */

.sg-row-slot {
  display: flex !important;
  align-items: center !important;
  gap: 14px !important;                    /* the row's own gap, between the two pills */
  flex: 0 0 auto !important;
  margin: 0 !important;
  padding: 0 !important;
}

/* A slot with nothing in it must take no space, or every other row holds a gap
   open for pills that are in the live row. */
.sg-row-slot:empty { display: none !important; }

/* The space is inside the scroller now, so the rows keep only the band's pad.
   Later and equally !important, so it beats the inset rule above. */
body.sg-cta-in-row.sg-cta-rides-row .tt-actions,
body.sg-cta-in-row.sg-cta-rides-row .reel-actions,
body.sg-cta-in-row.sg-cta-rides-row #sg-reels-rail,
body.sg-cta-in-row.sg-cta-rides-row #sg-sv-rail.sv-float,
body.sg-cta-in-row.sg-cta-rides-row #sg-profile-rail,
body.sg-cta-in-row.sg-cta-rides-row .sg-pr-host-capped {
  margin-left: 0 !important;
  padding-left: var(--sg-band-pad) !important;
}

/* In the row they are ordinary flex items: no fixed corner, no own offsets,
   no z-index above the content they now sit inside. Ids doubled and `html`
   prefixed because this has to beat the parked rules above, sg-dock.js and
   book-by-tap.css. */
html body.sg-cta-rides-row .sg-row-slot > #sg-continue-banner#sg-continue-banner,
html body.sg-cta-rides-row .sg-row-slot > #bchat-fab#bchat-fab,
html body.sg-cta-rides-row .sg-row-slot > #pchat-fab#pchat-fab,
html body.sg-cta-rides-row .sg-row-slot > #schat-fab#schat-fab,
html body.sg-cta-rides-row .sg-row-slot > #rchat-fab#rchat-fab,
html body.sg-cta-rides-row .sg-row-slot > #mchat-fab#mchat-fab,
html body.sg-cta-rides-row .sg-row-slot > #chat-fab#chat-fab {
  position: static !important;
  left: auto !important;
  right: auto !important;
  top: auto !important;
  bottom: auto !important;
  margin: 0 !important;
  transform: none !important;
  z-index: auto !important;
  flex: 0 0 auto !important;
  max-width: none !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
   THE SAME THREE BUTTONS, THE SAME LOOK, EVERY TAB (owner, 2026-09-18)

   rails.js builds Book / Talk / Ask AI from the app's own row markup, so they
   inherit the circles' size and colour wherever `.tt-actions` styles reach.
   These rules repeat that look for the rows that are NOT .tt-actions — the
   Profile rail, the ScanSquad float, the Reels strip — so the strip is one set
   of identical buttons on all five tabs instead of five near-misses.
   ═══════════════════════════════════════════════════════════════════════════ */

.sg-row-slot .tt-action.sg-row-trio {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  gap: var(--sg-btn-gap, 3px) !important;
  flex: 0 0 auto !important;
  cursor: pointer !important;
  -webkit-tap-highlight-color: transparent !important;
}

/* The circle is one-button.css's, read through var() rather than restated here:
   the numbers this block used to carry (42px, rgba(13,16,25,.62), border .10, no
   blur) were a copy of the Book rail's, and by 2026-09-19 the copy no longer
   matched anything on screen. Fallbacks are one-button.css's own values. */
.sg-row-slot .sg-row-trio > .tt-action-btn {
  width: var(--sg-btn-size, 44px) !important;
  height: var(--sg-btn-size, 44px) !important;
  border-radius: 50% !important;
  background: var(--sg-btn-bg, rgba(255, 255, 255, .07)) !important;
  border: var(--sg-btn-border-width, 1px) solid var(--sg-btn-border-color, rgba(255, 255, 255, .16)) !important;
  -webkit-backdrop-filter: var(--sg-btn-blur, blur(8px)) !important;
  backdrop-filter: var(--sg-btn-blur, blur(8px)) !important;
  box-shadow: var(--sg-btn-shadow, 0 2px 10px rgba(0, 0, 0, .25)) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  font-size: var(--sg-btn-icon, 20px) !important;
  line-height: 1 !important;
  opacity: 1 !important;
}

.sg-row-slot .sg-row-trio > .tt-action-btn svg {
  width: var(--sg-btn-icon, 20px) !important;
  height: var(--sg-btn-icon, 20px) !important;
  stroke: currentColor !important;
  color: #fff !important;
}

.sg-row-slot .sg-row-trio > .tt-action-btn:active { transform: scale(.9) !important; }

/* Caption, same source. It was 72% white here and 100% everywhere else, which is
   why Book / Talk / Ask AI read greyer than the buttons beside them. */
.sg-row-slot .sg-row-trio > .tt-action-label {
  display: block !important;
  font-size: var(--sg-btn-label-size, 10px) !important;
  font-weight: var(--sg-btn-label-weight, 600) !important;
  color: var(--sg-btn-label-color, #fff) !important;
  letter-spacing: var(--sg-btn-label-tracking, .2px) !important;
  text-shadow: var(--sg-btn-label-shadow, 0 1px 4px rgba(0, 0, 0, .8)) !important;
  white-space: nowrap !important;
  max-width: 60px !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  line-height: 1.1 !important;
}

/* The main bar and the floating Talk pill are the same doors as Ask AI and
   Talk, which are now items in the strip. Left where they were they simply sat
   on top of the new items: measured live on Book (the orange bar over "Book"
   and "Talk") and on Reels (the parent's "Gyms" pill over the framed row). So
   once the strip exists they are hidden — not removed, so every flow bound to
   them still works, and the sign-in case keeps its place in the strip via
   `.sg-cb-in-strip`. */
html body.sg-cta-rides-row #sg-continue-banner#sg-continue-banner:not(.sg-cb-in-strip),
html body.sg-cta-rides-row #bchat-fab#bchat-fab,
html body.sg-cta-rides-row #pchat-fab#pchat-fab,
html body.sg-cta-rides-row #schat-fab#schat-fab,
html body.sg-cta-rides-row #rchat-fab#rchat-fab,
html body.sg-cta-rides-row #mchat-fab#mchat-fab,
html body.sg-cta-rides-row #chat-fab#chat-fab {
  display: none !important;
}

/* In the strip the bar is an ordinary item again, so the rule above must not
   catch it: same specificity, later, and only when it is actually in there. */
html body.sg-cta-rides-row .sg-row-slot > #sg-continue-banner#sg-continue-banner {
  display: flex !important;
}


/* A row emptied into the host must not keep holding space or a background in
   the band; it is left in the DOM so whatever re-renders it still finds it. */
.sg-row-merged {
  display: none !important;
}

/* The card's own text — price, rating, opening hours — was written for a band
   with a 124px gap at its left. With the strip starting at the edge the two
   overlapped: measured live on Book, "£5.48/day" and "4.4 (136)" sat across the
   Book and Talk labels. The card's text ends above the band instead. */
body.sg-cta-rides-row .tt-info,
body.sg-cta-rides-row .tt-chips {
  padding-bottom: calc(var(--sg-band-height, 62px) + 4px) !important;
}

/* ── Content has to be able to scroll clear of the row ───────────────────────
   The containers above end at the nav and the row floats over them, which is
   right for a photo but wrong for a page that ends in text: on the Profile tab
   the closing line and the Channels section sat underneath the buttons (owner
   screenshot, 2026-09-19). Reserve the row's height at the end of the scroll,
   from the same variables the row is positioned with. */
/* …but a full-bleed card tab must NOT reserve it. Book and Partner draw a card
   that is `height: 100%` of this container, so the reserved 84px became dead
   space between the button row and the nav — the card, its name and its address
   all ended ~84px short of the bottom (owner screenshots, 2026-09-19 19:18).
   Reserve the band only on tabs that actually scroll text. `.sg-fullbleed` is
   set by rails.js; the `:has()` rule does the same where it is supported, so
   neither one alone has to win. */
html body main.sg-tab-content.sg-tab-content.sg-tab-content:not(.sg-fullbleed) {
  padding-bottom: calc(var(--sg-band-height, 72px) + 12px) !important;
}
html body main.sg-tab-content.sg-tab-content.sg-tab-content.sg-fullbleed,
html body main.sg-tab-content.sg-tab-content.sg-tab-content:has(.tt-card) {
  padding-bottom: 0 !important;
}

/* ── One bar per view, even across two documents ─────────────────────────────
   While the Reels frame is the view, the row is inside it and so is the frame's
   own copy of the bar. This document's bar has nothing to ride and used to stay
   fixed on top of the framed row's first button (owner screenshot, 2026-09-19).
   rails.js sets the class only while a painted reels frame is on screen and no
   row of this document's own is. */
html body.sg-cta-frame-owns #sg-continue-banner#sg-continue-banner {
  display: none !important;
}

/* Home and Create: the floating Talk pill and the main bar stay hidden whether
   or not a row has been built yet (rails.js#quietPills). The sign-in bar is
   the one exception and never gets .sg-cb-quiet. */
html body.sg-quiet-pills #sg-continue-banner#sg-continue-banner.sg-cb-quiet,
html body.sg-quiet-pills #bchat-fab#bchat-fab,
html body.sg-quiet-pills #pchat-fab#pchat-fab,
html body.sg-quiet-pills #schat-fab#schat-fab,
html body.sg-quiet-pills #rchat-fab#rchat-fab,
html body.sg-quiet-pills #mchat-fab#mchat-fab,
html body.sg-quiet-pills #chat-fab#chat-fab {
  display: none !important;
}

/* rails.js#paintTrio: an item this tab does not show. Same specificity as the
   flex rule above plus the class, and later, so it wins. */
.sg-row-slot .tt-action.sg-row-trio.sg-row-hidden {
  display: none !important;
}


/* ── THE ROW IS A RECTANGLE (owner, 2026-09-30) ─────────────────────────────
   "Home / Create / Shop / Profile are inside a fixed rectangle — make another
   fixed rectangle just above it for the other buttons." The band stops being a
   transparent strip over the video: it is a solid bar that touches the tab
   bar, and the reel (video, title, progress line, prompt chip) ends above it,
   so nothing is ever behind or on top of a button. */
:root {
  --sg-band-gap: 0px;
  --sg-band-height: 56px;
}
.tt-actions,
.reel-actions,
#sg-reels-rail,
#sg-sv-rail.sv-float,
#sg-profile-rail,
.sg-pr-host-capped {
  /* Task 11 (owner, 2026-10-04): "every tab is transparent or see through so we
     have full screen videos and photos". The band stays a rectangle — same
     height, same stacking, nothing moves — but it stops being paint. The video
     runs underneath it and the buttons read as glass on top, the way the tab
     bar already does. Translucent, never fully transparent: web.dev's
     backdrop-filter guidance is that the overlay must keep a tint of its own or
     the labels stop being legible over a bright frame. No blur — the rule below
     switches backdrop-filter off on this band on purpose (owner, 2026-09-30:
     "switching tabs is very slow"), so the tint is what carries contrast, same
     trade sg-glass.css already makes for the buttons. */
  background: rgba(10, 12, 20, .32) !important;
  border-top: 1px solid rgba(255, 255, 255, .10) !important;
  box-sizing: border-box !important;
  /* Above the tab pages (Create Studio is fixed at 8995 and used to cover the
     type row completely), below the bottom bar (8999) and the tab bar (9000). */
  z-index: 8996 !important;
}

/* ── AND IT LOOKS LIKE THE TAB BAR (owner, 2026-09-30, second pass) ──────────
   Same height (56px), same glass, buttons spread evenly as flat icon + label —
   a second tab bar, not a cluster of circles on a dark strip. */
.tt-actions,
.reel-actions,
#sg-reels-rail,
#sg-sv-rail.sv-float,
#sg-profile-rail,
.sg-pr-host-capped {
  justify-content: space-around !important;
  gap: 0 !important;
  padding: 0 !important;
  /* No blur: the bar is 98% opaque, and a 24px backdrop blur over a playing
     video is the single most expensive effect a phone GPU can be asked for
     (owner, 2026-09-30: "switching tabs is very slow"). */
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
.tt-actions > *,
.reel-actions .reel-action,
#sg-reels-rail > *,
#sg-profile-rail > *,
.sg-pr-host-capped > * {
  flex: 1 1 0 !important;
  min-width: 0 !important;
  gap: 2px !important;
  padding: 6px 4px !important;
}
.tt-actions .tt-action-btn,
.reel-actions .icon {
  width: 24px !important;
  height: 24px !important;
  min-width: 0 !important;
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  font-size: 20px !important;
}
.tt-actions .tt-action-btn svg,
.reel-actions .icon svg {
  width: 22px !important;
  height: 22px !important;
}
.tt-actions .tt-action-label,
.reel-actions .label,
#sg-reels-rail .sg-rr-label,
#sg-profile-rail .sg-rr-label,
.sg-pr-host-capped .sg-pr-label {
  font-size: 11px !important;
  letter-spacing: .2px !important;
  /* Task 11 (owner, 2026-10-04): the band is see-through now, so a label can
     land on a bright frame. Brighter ink plus a 1px shadow is what keeps it
     readable without giving the band its paint back. */
  color: rgba(255, 255, 255, .88) !important;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .75) !important;
}

/* ── EVERY BUTTON IN THE BAR IS FLAT, AND EVERY PAGE ENDS ABOVE THE BARS ─────
   (owner, 2026-09-30, third pass). Ask AI / Book / Talk (rails.js trio), the
   Create type buttons (squad-create.js) and the Profile rail all drop their
   circles and take the tab-bar look; the page underneath stops at the top of
   the button bar on every tab that has one. */
.tt-actions .sg-row-slot,
.reel-actions .sg-row-slot,
#sg-reels-rail .sg-row-slot,
#sg-sv-rail.sv-float .sg-row-slot,
#sg-profile-rail .sg-row-slot,
.sg-pr-host-capped .sg-row-slot {
  display: contents !important;
}
.sg-row-slot .tt-action.sg-row-trio,
#sg-sv-rail.sv-float .sg-sv-btn,
#sg-profile-rail > *,
.sg-pr-host-capped > * {
  flex: 1 1 0 !important;
  min-width: 0 !important;
  gap: 2px !important;
  padding: 6px 4px !important;
}
.sg-row-slot .sg-row-trio > .tt-action-btn,
.reel-actions .tt-action-btn,
#sg-sv-rail.sv-float .sv-circle,
#sg-profile-rail .sg-rr-circle,
.sg-pr-host-capped .sg-pr-circle {
  width: 24px !important;
  height: 24px !important;
  min-width: 0 !important;
  /* app's tap-target rule `.tt-action-btn{min-height:44px}` kept the trio's
     24px box 44px tall, so Ask AI / Book / Talk sat 14px lower than the row
     (owner screenshot, 2026-09-30). The whole 56px button is the tap target. */
  min-height: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  font-size: 20px !important;
  animation: none !important;
}
.sg-row-slot .sg-row-trio > .tt-action-btn svg,
#sg-sv-rail.sv-float .sv-circle svg,
#sg-profile-rail .sg-rr-circle svg,
.sg-pr-host-capped .sg-pr-circle svg {
  width: 22px !important;
  height: 22px !important;
}
#sg-sv-rail.sv-float .sv-dot { display: none !important; }
.sg-row-slot .sg-row-trio > .tt-action-label,
#sg-sv-rail.sv-float .sv-label {
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: .2px !important;
  /* Task 11 (owner, 2026-10-04): the band is see-through now, so a label can
     land on a bright frame. Brighter ink plus a 1px shadow is what keeps it
     readable without giving the band its paint back. */
  color: rgba(255, 255, 255, .88) !important;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .75) !important;
}
html body.sg-cta-rides-row .sg-tab-content:not(.reels-active) {
  bottom: calc(var(--sg-nav-h, 56px) + var(--sg-safe-b, 0px) + var(--sg-band-height, 56px)) !important;
}

/* ── PROFILE ROW, SAME LOOK AS EVERY OTHER ROW (owner, 2026-09-30) ──────────
   The app's own Book / Partner / Help circles (inline styles from
   sgRailCircle), the chatbot buttons (.sg-pr-circle, with live dots) and the
   in-row Sign in pill all take the flat tab-bar look. The row's own Book goes:
   the trio already has one (owner saw "Book Book"). */
.sg-pr-host-capped > :not(#sg-profile-rail-ext) > div:first-child,
.sg-pr-host-capped .sg-pr-circle,
#sg-profile-rail .sg-pr-circle,
#sg-profile-rail-ext .sg-pr-circle {
  width: 24px !important;
  height: 24px !important;
  border-radius: 0 !important;
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  font-size: 20px !important;
}
.sg-pr-host-capped > :not(#sg-profile-rail-ext) > div:first-child svg,
.sg-pr-host-capped .sg-pr-circle svg,
#sg-profile-rail .sg-pr-circle svg,
#sg-profile-rail-ext .sg-pr-circle svg {
  width: 22px !important;
  height: 22px !important;
}
.sg-pr-host-capped .sg-pr-dot,
#sg-profile-rail .sg-pr-dot,
#sg-profile-rail-ext .sg-pr-dot { display: none !important; }
.sg-pr-host-capped > * > span,
.sg-pr-host-capped .sg-pr-label,
#sg-profile-rail .sg-pr-label,
#sg-profile-rail-ext .sg-pr-label {
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: .2px !important;
  /* Task 11 (owner, 2026-10-04): the band is see-through now, so a label can
     land on a bright frame. Brighter ink plus a 1px shadow is what keeps it
     readable without giving the band its paint back. */
  color: rgba(255, 255, 255, .88) !important;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .75) !important;
}
.sg-pr-host-capped > *,
.sg-pr-host-capped .sg-pr-btn,
/* Task 18 (owner, 2026-09-30): Book / Talk / Ask AI kept the generic
   `flex:1 1 0; min-width:0` rule, so in the scrolling Profile row they shrank
   to 8px and piled onto Facebook. Same box as every other Profile button. */
#sg-profile-rail .sg-row-slot .tt-action.sg-row-trio,
.sg-pr-host-capped .sg-row-slot .tt-action.sg-row-trio,
#sg-profile-rail .sg-pr-btn,
#sg-profile-rail-ext .sg-pr-btn {
  flex: 0 0 auto !important;
  width: auto !important;
  min-width: 64px !important;
  gap: 2px !important;
  padding: 6px 4px !important;
}
.sg-pr-host-capped > button[aria-label="Book a gym"] { display: none !important; }
.sg-row-slot > #sg-continue-banner.sg-cb-in-strip {
  background: transparent !important;
  box-shadow: none !important;
  border: 0 !important;
}

/* ── TASK 54: BOOK AND PARTNER GO LAST (owner, 2026-09-30) ──────────────────
   "Move book and partner button to last." The Profile row is one flex line
   (the trio slot is display:contents, so its Book is a direct flex item), so
   `order` moves both to the end without touching the markup that builds them. */
.sg-pr-host-capped > *,
.sg-pr-host-capped .sg-row-slot > * { order: 0; }
.sg-pr-host-capped .sg-row-slot > .sg-row-trio[data-sg-row-act="book"],
#sg-profile-rail .sg-row-slot > .sg-row-trio[data-sg-row-act="book"] { order: 90 !important; }
.sg-pr-host-capped > button[aria-label="Partner"] { order: 91 !important; }

/* Owner 2026-10-09 (#8): remove all 3 orange buttons on Home - the Talk pill,
   the big Talk bar (same element, restyled by talk-bar.css) and the
   "Find gyms near me" bar. The class is set by rails.js on Home routes only. */
html.sg-home-clean #rchat-fab,
html.sg-home-clean #chat-fab,
html.sg-home-clean #bchat-fab,
html.sg-home-clean #pchat-fab,
html.sg-home-clean #schat-fab,
html.sg-home-clean #mchat-fab,
html.sg-home-clean #sg-continue-banner { display: none !important; }

/* Owner 2026-10-09 (#10): remove the "Find gyms near me" bar from every tab. */
#sg-continue-banner { display: none !important; }

/* #19 (owner 2026-10-10): no Talk button on any tab — the floating/row Talk pill is gone everywhere. */
html body #pchat-fab#pchat-fab{display:none!important}

/* #16 (owner 2026-10-11): "No button hidden under a button — all buttons in
   front in one horizontal scrollable row." The › / ‹ discs sat on top of (and
   between) row buttons, so they are switched off; the row still swipes. */
.sg-rail-scrollable::after,
.sg-rail-scroll-left::before,
.tt-actions.sg-rail-scroll-left::before {
  content: none !important;
  display: none !important;
}


/* ── sg-glass.css ── */
/* Task 165 (owner, 2026-10-02): "more transparent / glass skin like Tango" on
   every tab. One shared skin: chips, tags, pills and bars become frosted glass
   (see-through + blur + thin white edge) instead of solid grey blocks.
   Active items stay orange so the selected state is still obvious. */
:root {
  /* Owner 2026-10-04: one theme on every tab — these read sg-row-theme.css,
     the single source of truth, instead of a second set of values. The blur
     drops 14px -> 8px with it: the sampled area grows about 3x the radius per
     side, which is the measured cause of scroll jank on phones. */
  --sg-glass-bg: var(--sg-row-btn-bg, rgba(255, 255, 255, .07));
  --sg-glass-bg-hover: rgba(255, 255, 255, .16);
  --sg-glass-edge: var(--sg-row-edge, rgba(255, 255, 255, .16));
  --sg-glass-blur: var(--sg-row-blur, blur(8px)) saturate(160%);
  --sg-glass-on: var(--sg-row-on, rgba(255, 109, 0, .78));
  --sg-glass-on-edge: var(--sg-row-on-edge, rgba(255, 170, 100, .9));
}

/* Utility for new UI */
.sg-glass-chip,
#reels-search-button,
.sg-glass-sheet {
  background: var(--sg-glass-bg) !important;
  border: 1px solid var(--sg-glass-edge) !important;
  -webkit-backdrop-filter: var(--sg-glass-blur);
  backdrop-filter: var(--sg-glass-blur);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), 0 4px 18px rgba(0, 0, 0, .18);
}
.sg-glass-sheet { background: rgba(18, 20, 29, .62) !important; }

/* Chips / tags / pills across Home, Create, Shop, Chats, Profile */
[data-shop-cat],
.sv-chip,
.sv-mchip,
.tt-chip,
.sg-filter-pill,
.topic-pill,
.gd-pill,
.sg-pass-chip,
.sg-cal-quick-chip {
  background: rgba(255, 255, 255, .07) !important;
  border: 1px solid var(--sg-glass-edge) !important;
  color: #fff !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .10);
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important; /* speed: no blur on chips */
  transition: background .04s ease, transform .04s ease;
}
[data-shop-cat]:active, .sv-chip:active, .sv-mchip:active, .tt-chip:active,
.sg-filter-pill:active, .topic-pill:active, .gd-pill:active, .sg-glass-chip:active { transform: scale(.96); }
@media (hover: hover) {
  [data-shop-cat]:hover, .sv-chip:hover, .sv-mchip:hover, .tt-chip:hover,
  .sg-filter-pill:hover, .topic-pill:hover, .gd-pill:hover, .sg-glass-chip:hover { background: var(--sg-glass-bg-hover) !important; }
}

/* Selected state: orange glass */
[data-shop-cat][style*="#FF6D00"],
.sv-chip.on,
.sv-chip.active,
.tt-chip.active,
.sg-filter-pill.active,
.topic-pill.active,
.sg-pass-chip.selected {
  background: var(--sg-glass-on) !important;
  border-color: var(--sg-glass-on-edge) !important;
}

/* Bottom tab bar: frosted, video shows through (Tango) */
.sg-tab-bar {
  background: rgba(10, 10, 14, .38) !important;
  -webkit-backdrop-filter: var(--sg-glass-blur) !important;
  backdrop-filter: var(--sg-glass-blur) !important;
  border-top: 1px solid rgba(255, 255, 255, .10) !important;
}

/* Browsers without backdrop-filter: keep text readable */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  [data-shop-cat], .sv-chip, .sv-mchip, .tt-chip, .sg-filter-pill, .topic-pill, .gd-pill,
  .sg-pass-chip, .sg-glass-chip { background: rgba(40, 44, 56, .85) !important; }
  .sg-tab-bar, .sg-glass-sheet { background: rgba(14, 16, 22, .92) !important; }
}

/* Task 165 pass 2 (owner, 2026-10-02, YouTube Shorts camera screenshots):
   "make the heart transparent: just the icon border, inside see-through".
   Every action icon is now a thin white outline (no solid fill), and the
   Home rail sits in one see-through glass pill, like YouTube's side rail. */
html:root {
  --sg-btn-bg: rgba(255, 255, 255, .08);
  --sg-btn-border-color: rgba(255, 255, 255, .24);
  --sg-btn-blur: none; /* speed: see-through without the costly blur */
  --sg-btn-shadow: inset 0 1px 0 rgba(255, 255, 255, .10);
}
html body #sg-reel-row-host .reel-actions,
html body .reel-actions.sg-glass-rail {
  background: rgba(30, 30, 34, .28) !important;
  border: 1px solid rgba(255, 255, 255, .16) !important;
  -webkit-backdrop-filter: var(--sg-glass-blur) !important;
  backdrop-filter: var(--sg-glass-blur) !important;
  border-radius: 36px !important;
  padding: 12px 0 !important;
}
html body #sg-reel-row-host .reel-actions .icon,
html body #sg-reel-row-host .reel-actions .tt-action-btn {
  background: transparent !important; border: 0 !important; box-shadow: none !important;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .45)) !important;
}
html body #sg-reel-row-host .reel-actions .icon svg,
html body #sg-reel-row-host .reel-actions .icon svg.tt-fill,
html body #sg-reel-row-host .reel-actions .icon svg.tt-bold,
html body #sg-reel-row-host .reel-actions .tt-action-btn svg {
  fill: none !important; stroke: #fff !important; stroke-width: 1.7 !important;
  stroke-linecap: round; stroke-linejoin: round;
}
html body #sg-reel-row-host .reel-actions .icon svg path,
html body #sg-reel-row-host .reel-actions .icon svg rect,
html body #sg-reel-row-host .reel-actions .tt-action-btn svg path { fill: none !important; stroke: #fff !important; }
html body #sg-reel-row-host .reel-actions .icon svg circle { fill: #fff !important; stroke: none !important; }
/* Liked / reposted keep their colour, still outline-first like YouTube */
html body #sg-reel-row-host .reel-actions .reel-action[data-action="like"].sg-on .icon svg,
html body #sg-reel-row-host .reel-actions .reel-action[data-action="like"].sg-on .icon svg path { fill: #fe2c55 !important; stroke: #fe2c55 !important; }
html body #sg-reel-row-host .reel-actions .reel-action[data-action="repost"].sg-on .icon svg path { stroke: #22c55e !important; }

/* Round icon buttons and pills everywhere: see-through glass, white edge */
.sg-row-btn, .sg-icon-btn, #reels-search-button, #sg-hp-plus {
  background: rgba(255, 255, 255, .08) !important;
  border: 1px solid rgba(255, 255, 255, .24) !important;
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}
/* Home top tabs (Stories / For You / Following): plain text like TikTok, no boxes */
#reels-top-bar .reels-tab, #reels-top-bar [role="tab"], #reels-top-bar .sg-home-tab {
  background: transparent !important; border: 0 !important; box-shadow: none !important;
}
#reels-search-button svg, .sg-row-btn svg, .sg-icon-btn svg { fill: none !important; stroke: #fff !important; stroke-width: 1.7 !important; }

/* Owner 2026-10-02: Home search is a plain white icon top right (TikTok), no box */
html body #reels-search-button { background: transparent !important; border: 0 !important; box-shadow: none !important; width: 36px !important; height: 36px !important; }
html body #reels-search-button svg { width: 24px !important; height: 24px !important; stroke-width: 2 !important; filter: drop-shadow(0 1px 2px rgba(0,0,0,.5)); }


/* ── sg-fast.css ── */
/* Owner 2026-10-02: "every tab, screen, button and half sheet is slow and ugly".
   One app-wide layer of proven rules (Apple HIG, Material 3, web.dev):
   - instant taps: no 300ms double-tap wait, no grey flash, press feedback now
   - sheets slide on the GPU (transform only), 220ms, iOS curve
   - no backdrop blur except the tab bar (blur is the costliest paint on phones)
   - one button shape, one radius scale, calm secondary text */
html { -webkit-text-size-adjust: 100%; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; }
a, button, [role="button"], .sv-chip, .sv-mchip, input, label, select, textarea { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
button, [role="button"], .sv-chip, .sv-mchip, .sg-glass-chip, .creator-tab, [data-shop-cat] {
  transition: transform .04s ease, background-color .04s ease, opacity .04s ease !important;
}
button:active, [role="button"]:active, .sv-chip:active, .sv-mchip:active, .sg-glass-chip:active, .creator-tab:active, [data-shop-cat]:active { transform: scale(.96); }
button:disabled { transform: none !important; }
:focus-visible { outline: 2px solid rgba(255, 138, 31, .9); outline-offset: 2px; }

/* Half sheets: GPU slide, short and springy */
#sg-sv-sheet, .sg-sheet-container, [id$="-sheet"] > .sg-cmt-panel {
  will-change: transform;
  transition: transform .04s cubic-bezier(.32, .72, 0, 1) !important;
  border-top-left-radius: 22px; border-top-right-radius: 22px;
}
.sg-sheet-backdrop { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }

/* Speed: blur only where it earns its cost (tab bar + Home rail). Everything
   else is see-through without the blur pass. */
body *:not(.sg-tab-bar):not(.reel-actions):not(#sg-tab-bar) { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }

/* One look for secondary text and pill buttons */
.sv-note, .shs-sub, .sg-muted { color: #8b93a1 !important; }

