/* The phone's three new apps: OUTSIDE EXCHANGE, OUTSIDE and VIBE CHECK.

   THEY ARE NOT INSIDE THE DEVICE, AND THAT IS THE FIRST THING THIS FILE FIXES. outside-ui.js appends
   `.outside-screen` to `#duber-phone` — the full-screen overlay — not to `.duber-device`. The overlay
   is a centred grid, so the app screen lands in its own row UNDER the phone's title bar instead of in
   it. Rather than move it (that is duber-ui's DOM, not this sheet's), the screen is given the device's
   own width, rim, fill and shadow, and the bar's bottom corners are squared off while one of these
   apps is open. The two rows then read as one continuous phone with a seam you cannot see.

   WHAT IT INHERITS FROM duber.css, DELIBERATELY: the 390 px device width, the #120810f2 pinned-band
   fill from `.duber-dock`, the #ffffff07 / #ffffff10 card-and-hairline pair from `.duber-row`, the
   10 / 12 / 14 px radius ladder, the 9px→46px button ladder, Barlow Condensed 800 for every numeral,
   the `.phone-apps button[aria-selected]` treatment for every selected segment, and the 20 px pill
   from `.bf-specs li`. Nothing here invents a surface that is not already somewhere in that file.

   COLOUR IS BORROWED, NOT INVENTED. Each app takes a custom property the game already owns, so the
   phone gains three apps and the game gains no new palette:
     EXCHANGE   --cash-tint   (#a8eec1 — the wallet's green; this app is money)
     OUTSIDE    --album-orange(#f07842 — the record's orange; this app is the record's timeline)
     VIBE CHECK --vibe-tint   (#d4a9ff — the vibe purple, the same purple as the smoke)
     the one gold, --key-tint, is spent on exactly one thing: an unclaimed Golden Vibe sighting.
   Pink stays Duber's and is not used here.

   Loaded LAST, after duber.css and glass-controls.css, so equal-specificity rules win — which is why
   there is no `!important` anywhere below, including where this sheet has to undo a bare-tag rule from
   style.css (a class beats a tag on its own). */

/* Three new properties, and the reason for each:
   --os-up / --os-down are the EXACT two colours outside-ui.js strokes the sparkline and the price
   chart with (#7fd1a6 rising, #e08b8b falling). Defining them here means the number under a line and
   the line itself can never drift apart. --os-flat is the third state the ▬ glyph needs.
   Colour only ever REINFORCES: every one of these values ships with ▲ ▼ ▬ in the markup, so the
   readout survives being colour-blind, sun-washed or printed. */
:root{
 --os-up:#7fd1a6;
 --os-down:#e08b8b;
 --os-flat:#b3a4b0;
 --os-stat-h:40px;                /* one stats cell; the sticky header's height is derived from it */
 --os-gap:6px;
 --os-band:#120810f2;             /* the pinned-band fill, lifted straight from .duber-dock */
}

/* ---- the phone's chrome, so these read as apps of THIS phone -------------------------------------
   duber.css already tints the bar for BlueFin; the same three lines for the three new apps. The home
   grid in index.html already carries .app-exchange / .app-outside / .app-vibecheck and nothing had
   painted them yet, so their tiles are here too. */
.app-exchange{background:linear-gradient(160deg,#cdf7de,#39a06d)}
.app-outside{background:linear-gradient(160deg,#ffb98a,#d9531c);font-size:19px}
.app-vibecheck{background:linear-gradient(160deg,#e6cdff,#8358d2)}
#duber-phone[data-app="exchange"] .duber-bar{background:linear-gradient(180deg,#123a2b,#0a231a)}
#duber-phone[data-app="exchange"] .duber-device{border-color:#a8eec147}
#duber-phone[data-app="exchange"] :is(#phone-title,.phone-apps button[aria-selected="true"]){color:var(--cash-tint)}
#duber-phone[data-app="outside"] .duber-bar{background:linear-gradient(180deg,#4a2110,#2c1309)}
#duber-phone[data-app="outside"] .duber-device{border-color:#f0784247}
#duber-phone[data-app="outside"] :is(#phone-title,.phone-apps button[aria-selected="true"]){color:#ffb98a}
#duber-phone[data-app="vibecheck"] .duber-bar{background:linear-gradient(180deg,#2e1a4c,#1b0f2e)}
#duber-phone[data-app="vibecheck"] .duber-device{border-color:#d4a9ff47}
#duber-phone[data-app="vibecheck"] :is(#phone-title,.phone-apps button[aria-selected="true"]){color:var(--vibe-tint)}

/* ---- the screen ----------------------------------------------------------------------------------
   Same width and material as .duber-device, joined to the bar above it. max-height is what makes it
   the scroller rather than the window: 16px of overlay padding top and bottom plus the bar's ~46px. */
.outside-screen{
 width:min(390px,94vw);max-height:calc(100vh - 94px);
 padding:12px;display:grid;gap:9px;align-content:start;
 overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
 border:1px solid #ffffff1c;border-top:0;border-radius:0 0 26px 26px;
 background:linear-gradient(180deg,#160a12,#0c070d);
 box-shadow:0 26px 70px #000a;color:#f0e7ed;
 /* The head's height, and therefore where the tabs and the back button stop. Every term is a real
    measurement: two stat rows, the gap between them, 9+8 px of padding and the 1 px rule. */
 --os-rush-h:0px;
 --os-head-h:calc(var(--os-stat-h)*2 + var(--os-gap) + 18px + var(--os-rush-h))}
.outside-screen:has(.os-rush){--os-rush-h:calc(30px + var(--os-gap))}
/* duber.css writes the same line for .bluefin-screen. Kept for the same reason: display is a grid. */
.outside-screen[hidden]{display:none}
#duber-phone:is([data-app="exchange"],[data-app="outside"],[data-app="vibecheck"]) .duber-device{
 border-radius:26px 26px 0 0;border-bottom:0;box-shadow:0 0 0 1px #ffffff0d}
/* style.css sets `button{touch-action:none}` globally for the driving controls. These lists are made
   almost entirely of buttons, so without this a drag that starts on a row does not scroll the app at
   all. The chart is the one exception below — it is scrubbed, not scrolled. */
.outside-screen button{touch-action:pan-y}
.outside-screen p,.outside-screen h4{margin:0}

/* ---- the sticky head -----------------------------------------------------------------------------
   Cash and the tabs are the two things you navigate by, so neither scrolls away. The head pins at 0
   and the tabs pin directly beneath it; the disclosure line between them slides under the head, which
   is why the head is opaque. On a landscape phone the head unpins — see the bottom of the file. */
.os-head{position:sticky;top:0;z-index:3;display:grid;gap:var(--os-gap);
 margin:-12px -12px 0;padding:9px 12px 8px;border-bottom:1px solid #ffffff17;
 background:var(--os-band);-webkit-backdrop-filter:blur(13px);backdrop-filter:blur(13px)}

.os-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--os-gap)}
.os-vibecheck .os-stats{grid-template-columns:repeat(2,1fr)}
.os-stat{height:var(--os-stat-h);display:grid;align-content:center;gap:2px;padding:0 5px;
 text-align:center;border:1px solid #ffffff14;border-radius:10px;background:#ffffff08;overflow:hidden}
.os-stat small{font-size:11px;letter-spacing:.1em;line-height:1;color:#b294a3;
 overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.os-stat strong{font:800 17px/1 "Barlow Condensed",Arial,sans-serif;letter-spacing:.02em;color:#fff;
 font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The ▲▼▬ already sits in the value's text. This tint is the second signal, never the only one. */
.os-stat.is-up strong{color:var(--os-up)}
.os-stat.is-down strong{color:var(--os-down)}
.os-stat.is-flat strong{color:var(--os-flat)}
.os-up{color:var(--os-up)}
.os-down{color:var(--os-down)}
.os-flat{color:var(--os-flat)}

/* ---- Vibe Rush -----------------------------------------------------------------------------------
   Purple, and slow. One 4.2 s breath on the rim — no colour cycling, no scale, no rave. It is the
   only animation in this file, and it is off entirely under prefers-reduced-motion. */
.os-rush{display:flex;align-items:center;gap:8px;height:30px;padding:0 10px;
 border:1px solid #d4a9ff5c;border-radius:9px;background:#d4a9ff14;color:#ecd9ff;
 animation:os-rush-glow 4.2s ease-in-out infinite}
.os-rush b{font:800 13px/1 "Barlow Condensed",Arial,sans-serif;letter-spacing:.12em;color:var(--vibe-tint)}
.os-rush span{flex:1 1 0;min-width:0;font-size:11px;letter-spacing:.06em;
 overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.os-rush em{font-style:normal;font-size:11px;font-variant-numeric:tabular-nums;color:#c9b3da}
@keyframes os-rush-glow{
 0%,100%{box-shadow:0 0 0 1px #d4a9ff1f}
 50%{box-shadow:0 0 0 1px #d4a9ff52,0 0 15px #d4a9ff2b}}

/* ---- the disclosure ------------------------------------------------------------------------------
   SIMULATED MARKET / FICTIONAL WAGER. This is a real disclosure, not a footnote: it gets its own
   bordered band, full-strength letter-spacing and #d3c2ce — about 9:1 on this background. It is quiet
   because it is small and grey-lilac, not because it is hidden. */
.os-legal{padding:6px 9px;border:1px solid #ffffff1c;border-radius:8px;background:#ffffff0a;
 font-size:11px;line-height:1.35;letter-spacing:.1em;color:#d3c2ce;text-align:center}

/* ---- tabs ----------------------------------------------------------------------------------------
   Six tabs will not fit one 300 px row at a 34 px tap target, so they wrap to two rows rather than
   scroll sideways. Wrapping costs a row; sideways scrolling costs you the tabs you cannot see. */
.os-tabs{position:sticky;top:var(--os-head-h);z-index:2;display:flex;flex-wrap:wrap;gap:4px;
 margin:0 -12px;padding:7px 12px;background:var(--os-band);
 -webkit-backdrop-filter:blur(13px);backdrop-filter:blur(13px)}
.os-tab{flex:1 1 auto;min-height:34px;padding:0 9px;border:1px solid transparent;border-radius:8px;
 background:transparent;color:#c0aab6;font:inherit;font-weight:800;font-size:11px;line-height:1;
 letter-spacing:.08em;white-space:nowrap;cursor:pointer}
.os-tab.is-on{background:#ffffff14;border-color:#ffffff29;color:#fff}

/* ---- shared furniture ---------------------------------------------------------------------------- */
.os-sub{margin:6px 0 0;font-size:11px;font-weight:800;letter-spacing:.14em;color:#a08d9a}
.os-empty{padding:18px 10px;font-size:12px;line-height:1.5;color:#a08d9a;text-align:center}
.os-note{font-size:11px;line-height:1.5;color:#a08d9a}
.os-blurb{font-size:12px;line-height:1.55;color:#c8bcc6}
.os-warn{display:block;font-size:11px;line-height:1.4;letter-spacing:.04em;color:#ffb8b8}
.os-brand{font:800 19px/22px "Barlow Condensed",Arial,sans-serif;letter-spacing:.1em;color:#fff}
.os-outside .os-brand{color:#ffb98a}

/* The back button does not pin. It is 36 px at the very top of a detail screen and the head above it
   keeps the cash line in view; pinning it too would take a third band off a 300 px-tall scroller. */
.os-back{justify-self:start;min-height:36px;padding:8px 12px;border:1px solid #ffffff2b;
 border-radius:8px;background:#ffffff10;color:#e7d9e3;font:inherit;font-weight:700;font-size:11px;
 line-height:1;letter-spacing:.09em;cursor:pointer}

/* The one primary button per screen, sized like #duber-toggle and coloured per app. */
.os-go{width:100%;min-height:46px;padding:11px;border:0;border-radius:12px;font:inherit;
 font-weight:800;font-size:13px;line-height:1.2;letter-spacing:.07em;cursor:pointer;
 background:var(--cash-tint);color:#04160d}
.os-outside .os-go{background:var(--album-orange);color:#2a0d03}
.os-vibecheck .os-go{background:var(--vibe-tint);color:#1e0f36}
/* FOLLOWING / already-done: the action is spent, so the button empties out but keeps its place. */
.os-go.is-on{background:#ffffff12;color:#e7d9e3;box-shadow:inset 0 0 0 1px #ffffff2e}
.os-go:disabled{background:#ffffff12;color:#9b8794;box-shadow:inset 0 0 0 1px #ffffff1c;cursor:default}
.os-cancel{min-height:46px;padding:11px;border:1px solid #ffffff2e;border-radius:12px;
 background:#ffffff0f;color:#e2d4dd;font:inherit;font-weight:700;font-size:12px;line-height:1;
 letter-spacing:.06em;cursor:pointer}

.os-chip{min-height:34px;padding:8px 11px;border:1px solid #ffffff24;border-radius:20px;
 background:#ffffff0a;color:#dccfd8;font:inherit;font-weight:700;font-size:11px;line-height:1.3;
 letter-spacing:.04em;cursor:pointer}
.os-chip.is-on{border-color:#ffffff59;background:#ffffff1c;color:#fff}
.os-vibecheck .os-chip.is-on{border-color:#d4a9ff8f;background:#d4a9ff1f;color:#f0e2ff}

/* ================= OUTSIDE EXCHANGE ================================================================ */
.os-row{display:flex;align-items:center;gap:9px;width:100%;min-height:52px;padding:8px 10px;
 border:1px solid #ffffff10;border-radius:10px;background:#ffffff07;color:inherit;font:inherit;
 text-align:left;cursor:pointer}
/* A holding is something you own: it keeps the green rim the wallet and BlueFin use for ownership. */
.os-row.os-hold{border-color:#a8eec12e;background:#a8eec10a}
/* <i> tiles. The glyph and its two colours are set inline by outside-ui.js, so all this does is give
   them the shape and kill the italic they would otherwise inherit from the tag. */
.os-icon,.os-avatar{display:grid;place-items:center;flex:0 0 auto;width:34px;height:34px;
 border-radius:9px;font:800 13px/1 "Barlow Condensed",Arial,sans-serif;font-style:normal;
 letter-spacing:.02em;box-shadow:inset 0 1px 0 #ffffff33}
.os-row-mid{flex:1 1 auto;min-width:0;display:grid;gap:2px}
.os-row-mid strong{font-size:13px;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.os-row-mid small{font-size:11px;color:#a89aa4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.os-row-right{flex:0 0 auto;display:grid;gap:2px;justify-items:end;text-align:right}
.os-row-right strong{font-size:13px;color:#fff;font-variant-numeric:tabular-nums}
.os-row-right small{font-size:11px;font-variant-numeric:tabular-nums}
.os-spark{flex:0 0 auto;width:62px;height:20px;display:block}

.os-alloc{display:grid;gap:5px;padding:9px 11px;border:1px solid #ffffff10;border-radius:10px;
 background:#ffffff07}
.os-alloc-row{display:grid;grid-template-columns:52px minmax(0,1fr) 40px;gap:8px;align-items:center}
.os-alloc-row small{font-size:11px;color:#bfb0ba;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.os-alloc-row small:last-child{text-align:right;font-variant-numeric:tabular-nums}
/* Same track/fill pair as #duber-progress, so a proportion looks the same everywhere on this phone. */
.os-alloc-track{display:block;height:8px;border-radius:4px;background:#ffffff1a;overflow:hidden}
.os-alloc-track>b{display:block;height:100%;border-radius:4px;
 background:linear-gradient(90deg,#57b98d,var(--cash-tint))}

.os-news{display:grid;gap:4px;padding:9px 11px;border:1px solid #ffffff10;border-radius:10px;
 background:#ffffff07}
.os-news small{font-size:11px;letter-spacing:.12em;color:#9fb8ab}
.os-news p{font-size:12px;line-height:1.5;color:#e2d8df}

.os-tx{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:2px 9px;align-items:baseline;
 padding:8px 11px;border:1px solid #ffffff10;border-radius:10px;background:#ffffff07}
.os-tx small{font-size:11px;letter-spacing:.11em;color:#9b8794}
.os-tx strong{font-size:13px;font-variant-numeric:tabular-nums;text-align:right}
.os-tx em{grid-column:1/-1;font-style:normal;font-size:11px;line-height:1.4;color:#a89aa4}

.os-asset-head{display:flex;align-items:center;gap:10px}
.os-asset-head>div{flex:1 1 auto;min-width:0;display:grid;gap:2px}
.os-asset-head strong{font-size:15px;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.os-asset-head small{font-size:11px;font-variant-numeric:tabular-nums}
.os-star{flex:0 0 auto;min-height:34px;padding:8px 10px;border:1px solid #ffffff24;border-radius:8px;
 background:#ffffff0a;color:#c9bac4;font:inherit;font-weight:700;font-size:11px;line-height:1;
 letter-spacing:.07em;cursor:pointer}
.os-star.is-on{border-color:#a8eec173;background:#a8eec11c;color:var(--cash-tint)}

/* The canvas is authored at 300x130 and scaled by width alone; aspect-ratio holds the shape so the
   drawing never stretches, and the picking maths in outside-ui.js already divides by the rendered
   width. touch-action:none because this one IS dragged — scrubbing it must not scroll the list. */
.os-chart{display:block;width:100%;max-width:340px;height:auto;aspect-ratio:300/130;
 margin:0 auto;border:1px solid #ffffff10;border-radius:10px;background:#ffffff05;touch-action:none}
.os-ranges{display:flex;gap:4px}
.os-range{flex:1 1 0;min-height:34px;padding:0 4px;border:1px solid transparent;border-radius:8px;
 background:#ffffff08;color:#b7a7b3;font:inherit;font-weight:800;font-size:11px;line-height:1;
 letter-spacing:.06em;cursor:pointer}
.os-range.is-on{background:#ffffff14;border-color:#ffffff29;color:#fff}

.os-facts,.os-profile-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--os-gap)}
.os-facts>div,.os-profile-stats>div{display:grid;gap:2px;padding:7px 6px;text-align:center;
 border:1px solid #ffffff14;border-radius:10px;background:#ffffff08;overflow:hidden}
.os-facts small,.os-profile-stats small{font-size:11px;letter-spacing:.1em;line-height:1;color:#b294a3;
 overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.os-facts b,.os-profile-stats b{font-size:13px;color:#fff;font-variant-numeric:tabular-nums;
 overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.os-dividend{display:grid;gap:5px;padding:10px 11px;border:1px solid #a8eec12e;border-radius:12px;
 background:#a8eec10a}
.os-dividend strong{font-size:11px;letter-spacing:.11em;color:var(--cash-tint)}
.os-dividend p{font-size:12px;line-height:1.5;color:#dfd4dc}
.os-dividend small{font-size:11px;line-height:1.5;color:#a4a79f}

.os-trade{display:grid;gap:8px;padding:11px;border:1px solid #ffffff1f;border-radius:14px;
 background:#ffffff0a}
.os-sides{display:grid;grid-template-columns:1fr 1fr;gap:6px}
/* BUY and SELL both take the app's colour when selected. The word is the meaning; a green BUY and a
   red SELL would be the same information twice and the wrong information once, on the sell screen. */
.os-side{min-height:40px;border:1px solid #ffffff24;border-radius:10px;background:#ffffff0a;
 color:#c9bac4;font:inherit;font-weight:800;font-size:12px;line-height:1;letter-spacing:.1em;cursor:pointer}
.os-side.is-on{border-color:transparent;background:var(--cash-tint);color:#04160d}
.os-quick{display:flex;flex-wrap:wrap;gap:6px}
.os-quick .os-chip{flex:1 1 auto;padding:8px 6px;text-align:center}
.os-amount{display:grid;grid-template-columns:38px minmax(0,1fr) 38px 46px;gap:6px;align-items:center}
.os-step{min-height:38px;border:1px solid #ffffff24;border-radius:9px;background:#ffffff10;
 color:#f0e3ec;font:inherit;font-weight:800;font-size:16px;line-height:1;cursor:pointer}
/* A number input with spinners loses about 18 px of its width to arrows nobody can hit with a thumb;
   the − and + buttons either side are the spinner. */
.os-input{min-width:0;min-height:38px;padding:0 9px;border:1px solid #ffffff24;border-radius:9px;
 background:#00000038;color:#fff;font:inherit;font-weight:700;font-size:15px;text-align:center;
 font-variant-numeric:tabular-nums;-webkit-appearance:none;appearance:none;-moz-appearance:textfield}
.os-input::-webkit-outer-spin-button,.os-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.os-mode{min-height:38px;border:1px solid #ffffff24;border-radius:9px;background:#ffffff10;
 color:#f0e3ec;font:inherit;font-weight:800;font-size:11px;line-height:1;letter-spacing:.06em;cursor:pointer}
.os-preview{font-size:13px;line-height:1.4;color:#fff;font-variant-numeric:tabular-nums}

/* Information, not a promotion. No accent fill, no glow, no exclamation — a bordered aside in the
   purple the rest of the Vibe system uses, set at reading size and left-aligned like a footnote. */
.os-vibe-note{display:block;padding:7px 9px;border-left:2px solid #d4a9ff73;border-radius:0 8px 8px 0;
 background:#d4a9ff0d;font-size:11px;line-height:1.5;color:#cdbcd8}

.os-confirm{display:grid;gap:6px;padding:12px;border:1px solid #ffffff24;border-radius:14px;
 background:#ffffff0c}
.os-confirm>strong{font:800 19px/1 "Barlow Condensed",Arial,sans-serif;letter-spacing:.1em;color:#fff}
.os-confirm-row{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
 padding:6px 0;border-bottom:1px solid #ffffff0f}
.os-confirm-row small{flex:0 0 auto;font-size:11px;letter-spacing:.06em;color:#a89aa4}
.os-confirm-row b{min-width:0;font-size:12px;color:#fff;text-align:right;font-variant-numeric:tabular-nums}
.os-confirm-actions{display:grid;grid-template-columns:1fr 1.25fr;gap:8px;margin-top:4px}
.os-confirm-actions .os-go{min-height:46px}

/* ================= OUTSIDE ========================================================================= */
.os-outside .os-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--os-gap) 9px}
/* style.css styles the bare <header> tag as the game's FIXED top bar. .os-head is a div and is safe;
   .os-post-top is a real <header> and is not — see the reset further down. */
.os-outside{--os-head-h:calc(22px + 18px + var(--os-rush-h))}
.os-outside .os-head>small{flex:1 1 0;min-width:0;font-size:11px;line-height:22px;color:#b6a3ae;
 overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.os-outside .os-head .os-rush{flex:1 0 100%}

.os-post{display:grid;gap:7px;padding:10px 11px;border:1px solid #ffffff12;border-radius:12px;
 background:#ffffff07}
.os-post.is-you{border-color:#d4a9ff47;background:#d4a9ff0d}
/* THE RESET. Without these five declarations every post's header becomes `position:fixed;top:0` and
   the feed empties itself onto the game's tool bar. duber.css hit the same trap with .duber-head. */
.os-post-top{position:static;z-index:auto;display:flex;align-items:center;justify-content:space-between;
 gap:8px;padding:0}
.os-who{display:flex;align-items:center;gap:8px;min-width:0;min-height:40px;padding:0;border:0;
 background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}
.os-who>div{min-width:0;display:grid;gap:1px}
.os-who strong{font-size:13px;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.os-who small{font-size:11px;color:#a08d9a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.os-ticker{flex:0 0 auto;min-height:34px;padding:8px 10px;border:1px solid #f0784259;border-radius:8px;
 background:#f078421a;color:#ffbe93;font:inherit;font-weight:800;font-size:11px;line-height:1;
 letter-spacing:.08em;cursor:pointer}
.os-post-text{font-size:13px;line-height:1.5;color:#ece2e9;overflow-wrap:anywhere}

/* A rumour flag is a warning label, so it is quiet grey. is-live is the ONE gold in this file: an
   unclaimed Golden Vibe sighting, and nothing else anywhere gets to look like it. */
.os-flag{justify-self:start;padding:5px 9px;border:1px solid #ffffff24;border-radius:20px;
 font-size:11px;letter-spacing:.1em;color:#b6a3ae}
.os-flag.is-live{border-color:#ffd85e8c;background:#ffd85e1f;color:#ffe6a3;
 box-shadow:0 0 0 1px #ffd85e1f}
.os-post-acts{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:0;padding:0}
.os-act{min-height:34px;padding:8px 11px;border:1px solid #ffffff1c;border-radius:20px;
 background:#ffffff08;color:#c4b3bf;font:inherit;font-weight:700;font-size:11px;line-height:1;
 letter-spacing:.04em;cursor:pointer}
.os-act.is-on{border-color:#f0784273;background:#f078421f;color:#ffbe93}
.os-reply{display:grid;gap:2px;padding:6px 0 0 10px;border-left:2px solid #ffffff1c}
.os-reply small{font-size:11px;letter-spacing:.04em;color:#a08d9a}
.os-reply p{font-size:12px;line-height:1.45;color:#cdc0c9}

.os-trend{display:grid;gap:3px;width:100%;min-height:52px;padding:9px 11px;border:1px solid #ffffff12;
 border-radius:10px;background:#ffffff07;color:inherit;font:inherit;text-align:left;cursor:pointer}
.os-trend strong{font-size:13px;color:#ffbe93}
.os-trend small{font-size:11px;line-height:1.4;color:#bcaeb7}
.os-trend em{font-style:normal;font-size:11px;letter-spacing:.06em;color:#93808d}

/* The composer's chips are whole sentences, not percentages, so here a chip is a block that wraps. */
.os-composer{display:grid;gap:6px;padding:10px 11px;border:1px solid #ffffff14;border-radius:12px;
 background:#ffffff08}
.os-composer>small{font-size:11px;letter-spacing:.13em;color:#a08d9a}
.os-composer .os-chip{width:100%;border-radius:10px;text-align:left;line-height:1.4}

.os-profile{display:flex;align-items:flex-start;gap:10px}
.os-profile>div{min-width:0;display:grid;gap:2px}
.os-profile strong{font-size:15px;color:#fff}
.os-profile small{font-size:11px;color:#a08d9a}
.os-profile p{font-size:12px;line-height:1.5;color:#c8bcc6}
.os-accuracy{display:grid;gap:3px;padding:9px 11px;border:1px solid #ffffff14;border-radius:10px;
 background:#ffffff08}
.os-accuracy small{font-size:11px;letter-spacing:.13em;color:#a08d9a}
.os-accuracy b{font-size:12px;line-height:1.45;color:#fff}
.os-badges{display:flex;flex-wrap:wrap;gap:5px}
.os-badge{padding:5px 9px;border:1px solid #ffffff1f;border-radius:20px;font-size:11px;color:#dccfd8}

/* ================= VIBE CHECK ====================================================================== */
.os-wager{display:grid;gap:6px;padding:11px;border:1px solid #ffffff14;border-radius:12px;
 background:#ffffff08}
.os-wager>strong{font-size:14px;line-height:1.3;color:#fff}
.os-wager>small{font-size:11px;line-height:1.45;color:#bcaeb7}
.os-wager>em{font-style:normal;font-size:11px;letter-spacing:.06em;color:#cdbcd8;
 font-variant-numeric:tabular-nums}
.os-wager.is-live{border-color:#d4a9ff5c;background:#d4a9ff12}
.os-wager-progress{padding-left:9px;border-left:2px solid #d4a9ff8c;font-size:12px;line-height:1.45;
 color:#e4d7ef}
.os-terms{font-size:11px;line-height:1.5;color:#a89aa4;font-variant-numeric:tabular-nums}
.os-stakes{display:flex;flex-wrap:wrap;gap:6px}
.os-stakes .os-chip{flex:1 1 auto;min-width:56px;text-align:center;font-variant-numeric:tabular-nums}

/* Rarer and better-paying, marked by a word rather than by being louder. The orange rim is a shade
   the game already owns; the gold stays reserved for a Golden Vibe. The brief calls this `.os-rare`
   and outside-ui.js writes `is-rare` — both are matched, so renaming one cannot silently un-style it. */
.os-wager.is-rare,.os-wager.os-rare{border-color:#f0784273;background:#f078420f}
.os-wager.is-rare::before,.os-wager.os-rare::before{content:"RARE";justify-self:start;
 padding:4px 9px;border:1px solid #f0784273;border-radius:20px;font-size:11px;font-weight:800;
 letter-spacing:.14em;color:#ffbe93}
/* Settled: the <em> already reads WON / LOST / REFUNDED, so the tint is the second signal. */
.os-wager.is-won{border-color:#7fd1a659;background:#7fd1a60f}
.os-wager.is-won>em{color:var(--os-up)}
.os-wager.is-lost{border-color:#e08b8b47}
.os-wager.is-lost>em{color:var(--os-down)}
.os-wager.is-refunded{border-color:#ffb03a4d}
.os-wager.is-refunded>em{color:#ffb03a}

/* ---- motion -------------------------------------------------------------------------------------
   The rush chip keeps the bright half of its pulse so it still reads as live, it just stops moving. */
@media(prefers-reduced-motion:reduce){
 .os-rush{animation:none;box-shadow:0 0 0 1px #d4a9ff52}
}

/* ---- responsive ----------------------------------------------------------------------------------
   The same three phone breakpoints duber.css uses, doing the same thing to the same parts. */
@media(max-height:560px){
 :root{--os-stat-h:36px}
 .outside-screen{width:min(440px,94vw);max-height:calc(100vh - 78px);padding:10px;gap:8px;
  border-radius:0 0 18px 18px}
 #duber-phone:is([data-app="exchange"],[data-app="outside"],[data-app="vibecheck"]) .duber-device{
  border-radius:18px 18px 0 0}
 .os-head{margin:-10px -10px 0;padding:9px 10px 8px}
 .os-tabs{margin:0 -10px;padding:6px 10px}
 .os-chart{max-width:300px}
}
/* A phone in landscape. The scroller is about 380 px tall here. */
@media(max-height:460px){
 :root{--os-stat-h:32px}
 .outside-screen{width:min(470px,96vw);max-height:calc(100vh - 68px);padding:9px;gap:7px}
 .os-head{margin:-9px -9px 0;padding:9px 9px 8px}
 .os-tabs{margin:0 -9px;padding:5px 9px;gap:3px}
 .os-tab{padding:0 7px}
 .os-stat strong{font-size:15px}
 .os-go{min-height:44px}
 .os-cancel{min-height:44px}
 .os-chart{max-width:260px}
 .os-facts,.os-profile-stats{grid-template-columns:repeat(2,1fr)}
}
/* THE ONE THING THIS FILE DOES DIFFERENTLY FROM THE BRIEF, AND ON PURPOSE.
   On an SE-class landscape phone the scroll area is about 300 px tall. A pinned head there is ~84 px
   of it — more than a quarter of the screen permanently spent on six numbers you have already read —
   and the list it is supposed to help you read gets what is left. So below 400 px the head scrolls
   with the content and only the TABS stay pinned, because the tabs are the thing you actually keep
   reaching for. Nothing is hidden or dropped; one band stops being sticky. duber.css makes the same
   trade at the same size when it lets the hero collapse and the lifetime totals step out. */
@media(max-height:400px){
 .os-head{position:static;margin-bottom:0}
 .os-tabs{top:0}
 .outside-screen{max-height:calc(100vh - 58px);gap:6px}
}
@media(max-height:360px){
 :root{--os-stat-h:30px}
 .outside-screen{padding:8px;border-radius:0 0 14px 14px;max-height:calc(100vh - 52px)}
 #duber-phone:is([data-app="exchange"],[data-app="outside"],[data-app="vibecheck"]) .duber-device{
  border-radius:14px 14px 0 0}
 /* The head is static at this size (see the 400px rule), so its padding no longer has to
    match the --os-head-h term and can give the list its six pixels back. */
 .os-head{margin:-8px -8px 0;padding:6px 8px 5px}
 .os-tabs{margin:0 -8px;padding:4px 8px}
 .os-stat strong{font-size:14px}
 .os-chart{max-width:230px}
}
/* A narrow portrait phone: the widest fixed grid in the file is the amount row, so it is the one that
   has to give. Nothing else here has a fixed column that can overflow 300 px. */
@media(max-width:340px){
 .os-amount{grid-template-columns:36px minmax(0,1fr) 36px 42px;gap:5px}
 .os-alloc-row{grid-template-columns:44px minmax(0,1fr) 34px}
 .os-facts,.os-profile-stats{grid-template-columns:repeat(2,1fr)}
}

/* ---- the Vibe Rush chip, on the driving HUD --------------------------------------------------------
   The one piece of this expansion that lives OUTSIDE the phone, so it obeys the driving HUD's rules
   rather than the phone's: it sits in the bottom-left column directly above CATCH A VIBE, which is
   the only column with room, and it never goes near the wheel, the pedals, the GPS, the destination
   arrow, the street sign, Now Playing or a Duber request. Those are the things the player is acting
   on; this is a thing the player is glancing at.

   It is only ever visible while driving or on foot — `paintVibeRush()` hides it everywhere else. */
#vibe-rush-hud{
 position:fixed;z-index:13;
 left:var(--drive-edge,14px);
 bottom:calc(178px + var(--guide-height,0px) + env(safe-area-inset-bottom));
 display:flex;align-items:baseline;gap:8px;
 padding:6px 11px;border-radius:14px;
 background:linear-gradient(150deg,#2a1140e0,#160a22cc);
 border:1px solid #c79bff4d;
 box-shadow:0 0 18px #a56bff26,inset 0 1px 0 #ffffff1f;
 -webkit-backdrop-filter:blur(12px) saturate(1.25);backdrop-filter:blur(12px) saturate(1.25);
 pointer-events:none;
 animation:os-rush-breath 4.2s ease-in-out infinite;
}
#vibe-rush-hud b{
 font:800 13px/1 "Barlow Condensed",Arial,sans-serif;letter-spacing:.09em;
 color:#e7d2ff;text-transform:uppercase;white-space:nowrap;
}
#vibe-rush-hud span{
 font:700 11px/1 "Barlow Condensed",Arial,sans-serif;letter-spacing:.07em;
 color:#c0a8d8;white-space:nowrap;
}
#vibe-rush-hud em{
 font:800 13px/1 "Barlow Condensed",Arial,sans-serif;font-style:normal;
 font-variant-numeric:tabular-nums;color:#f0e3ff;margin-left:auto;
}
/* The top tier is the only one that gets a brighter rim: it is rare and it should read as rare. */
#vibe-rush-hud[data-tier="immaculate"]{border-color:#d9b6ff85;box-shadow:0 0 26px #b57cff3d,inset 0 1px 0 #ffffff29}
@keyframes os-rush-breath{0%,100%{box-shadow:0 0 14px #a56bff1f,inset 0 1px 0 #ffffff1f}
 50%{box-shadow:0 0 24px #a56bff3d,inset 0 1px 0 #ffffff29}}
@media(prefers-reduced-motion:reduce){#vibe-rush-hud{animation:none}}

/* Short landscape phones: the bottom-left column is tight, so it tucks up under the street sign
   instead, which is the other place nothing is being aimed at. */
@media(orientation:landscape) and (max-height:520px){
 #vibe-rush-hud{bottom:auto;top:calc(96px + env(safe-area-inset-top));padding:4px 9px;gap:6px}
 #vibe-rush-hud b{font-size:12px}
 #vibe-rush-hud span{font-size:10px}
 #vibe-rush-hud em{font-size:12px}
}
/* While the phone, the map or a menu is up, the chip has nothing to add. */
:root:not(.is-driving):not(.is-afoot) #vibe-rush-hud{display:none}
