/* ==========================================================================
   TIER — design system
   Loads last. Owns tokens, the overhead light, and every surface.
   See DESIGN.md for the contract this file implements.
   ========================================================================== */

:root {
    color-scheme: dark;

    /* Sampled from the reference screenshot rather than guessed: the page is
       near-black but not #000, and panels are noticeably lighter than the iOS
       system grey I had been using. */
    --bg: #1a1a1a;
    --surface-1: #2c2b31;
    --surface-2: #3a3940;
    --surface-3: #47464e;
    --hairline: rgba(255, 255, 255, .10);
    --hairline-strong: rgba(255, 255, 255, .16);

    --ink: #ffffff;
    /* Secondary/tertiary text has to clear 4.5:1 on --surface-1. The previous
       .56/.34 pair measured ~3.6:1 and ~2.6:1 and failed the contrast rule. */
    --ink-2: rgba(255, 255, 255, .72);
    --ink-3: rgba(255, 255, 255, .58);

    /* One stroke weight for every icon in the same layer. */
    --icon-stroke: 2;

    --accent: #3d51fe;
    --accent-ink: #ffffff;
    --danger: #ff453a;
    --success: #30d158;

    /* The overhead light. --glow-primary/-bloom are re-written at runtime by
       app.js so the room takes the colour of the pack being built. */
    --glow-primary: #2e49fb;
    --glow-bloom: #3ad4ff;
    --glow-strength: 1;
    /* Handed to Telegram.setHeaderColor so the client chrome and the top of the
       glow are the same colour and the surface reads as continuous. */
    --glow-chrome: #2f4bfb;

    /* Telegram/iOS list geometry, taken from the reference bundle. */
    --tg-radius: 16px;
    --tg-separator: #3d3d3f;
    --tg-row-min: 52px;
    --tg-row-pad: 16px;
    --tg-icon: 40px;

    /* portals.css repoints --ui-font at the static SFProText faces (400/500/
       600/700), which silently snaps every 510/590 to 500/600 and blunts the
       whole scale. The variable SF Pro is already loaded — use it. */
    --ui-font: "SF Pro", -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
    --pm-font: var(--ui-font);

    --w-reg: 400;
    --w-med: 510;
    --w-semi: 590;
    --w-bold: 700;

    --r-xs: 8px;
    --r-sm: 12px;
    --r-md: 14px;
    --r-lg: 16px;
    --r-xl: 28px;
    --r-pill: 999px;

    --gutter: 16px;
    --content-max: 520px;

    --e-out: cubic-bezier(.22, 1, .36, 1);
    --e-sharp: cubic-bezier(.86, 0, .07, 1);
    --e-sheet: cubic-bezier(.32, .72, 0, 1);
    --t-fast: 150ms;
    --t-base: 260ms;
    --t-slow: 380ms;

    --safe-b: env(safe-area-inset-bottom, 0px);
    --safe-t: env(safe-area-inset-top, 0px);
    --tabbar-h: 64px;
}

/* --------------------------------------------------------------------------
   Retire the old decorative stack: four drifting aurora blobs + grain + a
   vignette that darkened the middle of every screen. One directed light
   replaces all of it.
   -------------------------------------------------------------------------- */
.lg-ambient,
.lg-grain,
.lg-vignette {
    display: none !important;
}

html {
    background: var(--bg) !important;
}

body.oem-body {
    background: var(--bg);
    color: var(--ink);
    font-family: "SF Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: 17px;
    line-height: 22px;
    font-weight: var(--w-reg);
    letter-spacing: 0;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* --------------------------------------------------------------------------
   The overhead light
   Layer 1 wash from the top edge, layer 2 the low bloom, layer 3 resolves it
   back into page black. The skirt extends the wash 1000px above the scroll
   origin so it bleeds into the Telegram header and survives overscroll.
   -------------------------------------------------------------------------- */
.tier-glow {
    position: fixed;
    inset: 0 0 auto 0;
    height: 100%;
    z-index: -3;
    pointer-events: none;
    opacity: var(--glow-strength);
    transition: opacity var(--t-slow) var(--e-out);
    /* Stop positions traced off the reference: saturated only through the top
       third, fully resolved into the page by ~62%. Mine ran blue the whole way
       down, which is why it read as half the screen being painted. */
    background:
        radial-gradient(64% 30% at 50% 8%,
            color-mix(in srgb, var(--glow-bloom) 40%, transparent), transparent 70%),
        linear-gradient(to bottom,
            var(--glow-primary) 0%,
            color-mix(in srgb, var(--glow-primary) 88%, var(--bg)) 18%,
            color-mix(in srgb, var(--glow-primary) 46%, var(--bg)) 34%,
            color-mix(in srgb, var(--glow-primary) 14%, var(--bg)) 50%,
            var(--bg) 62%);
}

.tier-glow__skirt {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1000px;
    transform: translateY(-100%);
    background: var(--glow-primary);
}

/* Not decoration: a 1px paint on an 80x80 canvas promotes the layer to the GPU
   so the large gradient above does not band or judder in Telegram's WebView. */
.tier-glow__canvas {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 0;
    opacity: 0;
}

/* The glow colours cross-fade when the user changes their pack colour. */
@supports (transition: --glow-primary 1s) {
    :root {
        transition: --glow-primary var(--t-slow) var(--e-out),
                    --glow-bloom var(--t-slow) var(--e-out);
    }
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */
/* The old build padded every block individually with `margin: 0 20px` and
   pinned the page to `padding: … 0 … !important`. One gutter on the page is
   the single source of truth now, so the per-block margins are zeroed. */
.ui-page.oem-page {
    box-sizing: border-box;
    width: 100%;
    max-width: var(--content-max);
    margin-inline: auto;
    padding-inline: var(--gutter) !important;
    padding-top: calc(var(--tier-top, 0px) + 12px + var(--safe-t)) !important;
    padding-bottom: calc(var(--tabbar-h) + var(--safe-b) + 40px) !important;
}

.market-brandbar,
.market-hero,
.market-catalog,
.oem-pager.market-pager {
    margin-left: 0;
    margin-right: 0;
}

/* Several legacy rules set display on elements that also carry [hidden]; the
   attribute has to win or hidden blocks keep painting. */
[hidden] {
    display: none !important;
}

/* --------------------------------------------------------------------------
   Type roles
   Hierarchy is size + weight + colour. The old build set 700 on everything,
   which is why nothing read as primary.
   -------------------------------------------------------------------------- */
.ui-row-title,
.oem-sheet-title {
    font-size: 17px;
    line-height: 22px;
    font-weight: var(--w-med);
    letter-spacing: 0;
    color: var(--ink);
}

.ui-row-subtitle,
.ui-notice {
    font-size: 13px;
    line-height: 16px;
    font-weight: var(--w-reg);
    letter-spacing: .01em;
    color: var(--ink-2);
}

.ui-modal-title {
    font-size: 22px;
    line-height: 28px;
    font-weight: var(--w-semi);
    letter-spacing: -.01em;
    color: var(--ink);
}

/* --------------------------------------------------------------------------
   Filter pill + result count
   -------------------------------------------------------------------------- */
.market-filter-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 16px;
}

/* Reference filter chip: 40px tall, fully rounded, blurred elevated fill. */
.market-filter-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 40px;
    padding: 0 14px;
    border-radius: var(--r-pill);
    border: 0;
    background: var(--surface-1);
    color: var(--ink);
    font-size: 15px;
    line-height: 20px;
    font-weight: var(--w-med);
    letter-spacing: 0;
    transition: background var(--t-fast) var(--e-out),
                transform var(--t-fast) var(--e-out);
}

.market-filter-pill:active {
    background: var(--surface-2);
    transform: scale(.97);
}

.market-filter-icon {
    display: inline-flex;
    color: var(--accent);
}

/* app.js injects the chevron SVG here — style it, never draw a second one. */
#collectionChevron {
    display: inline-flex;
    color: var(--ink-3);
}

#collectionChevron svg {
    width: 16px;
    height: 16px;
}

/* Specular ring the old glass layer painted on every pill. */
.market-filter-pill::before {
    display: none;
}

.market-result-count {
    font-size: 13px;
    line-height: 16px;
    font-weight: var(--w-med);
    letter-spacing: .01em;
    color: var(--ink-3);
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Template grid + tile
   Tap the tile to select. The pencil in the corner opens that emoji's own
   editor. No repeated "Добавить" button under every card.
   -------------------------------------------------------------------------- */
/* Telegram shows emoji as a dense grid of bare artwork inside one grouped
   panel — no per-item card, border or badge. Cards around each template were
   the thing that made this read as a web grid instead of a picker. */
.oem-template-grid.market-template-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 4px;
    margin-bottom: 20px;
    padding: 8px;
    border-radius: var(--tg-radius);
    background: var(--surface-1);
}

.oem-template-tile {
    position: relative;
    border-radius: 14px;
    background: none;
    border: 0;
    overflow: hidden;
    transition: transform var(--t-base) var(--e-out),
                background var(--t-base) var(--e-out);
}

.oem-template-tile:active {
    transform: scale(.97);
}

.market-card-preview-button {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

/* glass.css wraps every cell in a frosted "lens" — border, specular edge and a
   pool of light under the art. That is what made the grid read as a wall of
   cards; the picker wants bare artwork on one panel. */
.market-template-grid .oem-template-preview,
.oem-template-preview {
    aspect-ratio: 1;
    display: grid;
    place-items: center;
    padding: 6px;
    border-radius: 14px;
    background: none !important;
    background-color: transparent !important;
    box-shadow: none !important;
    border: 0 !important;
}

.market-template-grid .oem-template-preview::before,
.market-template-grid .oem-template-preview::after {
    display: none !important;
}

.market-template-grid .oem-template-tile--selected .oem-template-preview {
    background-color: color-mix(in srgb, var(--accent) 30%, transparent) !important;
}

.oem-template-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    opacity: 0;
    transition: opacity var(--t-base) var(--e-out);
}

.oem-template-img.is-loaded {
    opacity: 1;
}

/* Selected: accent ring + tick. The ring is drawn inset so it never shifts
   layout, and the tile lifts onto a faintly tinted surface. */
.oem-template-tile--selected {
    background: color-mix(in srgb, var(--accent) 26%, transparent);
}

.tier-tile-check {
    position: absolute;
    top: 3px;
    right: 3px;
    width: 18px;
    height: 18px;
    border-radius: var(--r-pill);
    display: grid;
    place-items: center;
    background: var(--accent);
    color: var(--accent-ink);
    opacity: 0;
    transform: scale(.6);
    transition: opacity var(--t-fast) var(--e-out),
                transform var(--t-base) var(--e-out);
    pointer-events: none;
}

.oem-template-tile--selected .tier-tile-check {
    opacity: 1;
    transform: scale(1);
}

/* Per-emoji editing moved into the cart, where the selection actually lives —
   a pencil on every grid cell was the bulk of the visual noise. */
.market-cart-item--editable {
    position: relative;
    cursor: pointer;
}

.market-cart-edit {
    position: absolute;
    left: 4px;
    bottom: 4px;
    z-index: 4;
    width: 20px;
    height: 20px;
    border-radius: var(--r-pill);
    display: grid;
    place-items: center;
    background: rgba(0, 0, 0, .62);
    color: #fff;
    pointer-events: none;
}

.market-cart-edit svg {
    width: 11px;
    height: 11px;
}

.market-cart-edit-hint {
    margin: 10px 4px 22px;
    font-size: 13px;
    line-height: 17px;
    color: var(--ink-3);
}

/* The old per-tile action strip is replaced by the selection bar. */
.market-card-actions {
    display: none !important;
}

/* --------------------------------------------------------------------------
   Pager
   -------------------------------------------------------------------------- */
.oem-pager.market-pager {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px;
    border-radius: var(--r-lg);
    background: var(--surface-1);
    border: 1px solid var(--hairline);
    backdrop-filter: none;
}

.oem-pager-body {
    flex: 1;
    text-align: center;
    display: grid;
    gap: 2px;
}

.market-page-button.oem-nav-btn {
    width: 40px;
    height: 40px;
    flex: none;
    border-radius: var(--r-sm);
    border: 1px solid var(--hairline);
    background: var(--surface-1);
    color: var(--ink);
    display: grid;
    place-items: center;
    transition: background var(--t-fast) var(--e-out),
                transform var(--t-fast) var(--e-out),
                opacity var(--t-fast) var(--e-out);
}

.market-page-button.oem-nav-btn:active:not(:disabled) {
    background: var(--surface-2);
    transform: scale(.92);
}

.market-page-button:disabled {
    opacity: .28;
}

/* --------------------------------------------------------------------------
   Bottom tab bar
   Floats, therefore glass — but it carries a scrim so page content is never
   legible straight through it. The old build failed exactly here.
   -------------------------------------------------------------------------- */
/* No transform on the floating chrome: a transformed element becomes the
   containing block for its position:fixed children, which silently breaks the
   full-width scrim below. Centred with auto margins instead. */
/* Sized to its contents and centred. Stretching two tabs across the full width
   left them stranded at opposite edges, which is what read as "crooked".
   Solid fill, no backdrop blur — the project's design rules ban frosted glass
   and it was the "liquid glass that doesn't belong" in this UI. */
.market-tabbar {
    position: fixed;
    left: 0;
    right: 0;
    margin-inline: auto;
    transform: none;
    bottom: calc(var(--safe-b) + 12px);
    width: max-content;
    max-width: calc(100% - 32px);
    height: var(--tabbar-h);
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(96px, auto);
    align-items: stretch;
    padding: 5px;
    gap: 4px;
    border-radius: var(--r-pill);
    background: var(--surface-1);
    border: 0;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: 0 10px 34px rgba(0, 0, 0, .55);
    z-index: 40;
}

.market-tabbar::before,
.market-tabbar::after {
    display: none;
}

/* Fades the page out beneath the floating bar so nothing is ever legible
   straight through it. Separate element — see the note in index.html. */
.tier-bottom-scrim {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: calc(var(--tabbar-h) + var(--safe-b) + 52px);
    background: linear-gradient(to top, var(--bg) 42%, rgba(0, 0, 0, .88) 72%, transparent);
    z-index: 39;
    pointer-events: none;
    transition: height var(--t-base) var(--e-out);
}

/* The selection dock stacks above the tab bar, so the scrim has to grow to
   cover it too — otherwise tiles stay legible between the two. */
body.market-has-cart .tier-bottom-scrim {
    height: calc(var(--tabbar-h) + var(--safe-b) + 140px);
}

.market-tabbar-item {
    display: grid;
    grid-auto-rows: max-content;
    justify-items: center;
    align-content: center;
    gap: 3px;
    height: 100%;
    border: 0;
    border-radius: var(--r-pill);
    background: none;
    color: var(--ink-3);
    font-size: 11px;
    line-height: 13px;
    font-weight: var(--w-med);
    letter-spacing: .01em;
    transition: color var(--t-base) var(--e-out),
                background var(--t-base) var(--e-out);
}

.market-tabbar-icon {
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
}

.market-tabbar-icon svg {
    width: 21px;
    height: 21px;
}

.market-tabbar-label {
    display: block;
}

/* Reference marks the active tab with a filled pill and accent-coloured text. */
.market-tabbar-item.is-active {
    color: var(--accent);
    background: var(--surface-2);
    font-weight: var(--w-semi);
}

/* 44pt minimum touch target. */
.market-tabbar-item {
    min-width: 96px;
    min-height: 44px;
    padding: 0 14px;
}

.market-tabbar-item:active {
    transform: none;
}

/* glass.css hides tab-bar icons with !important; the reference bar is
   icon-over-label, so that has to be undone here. */
.market-tabbar-icon {
    display: grid !important;
}

/* --------------------------------------------------------------------------
   Selection bar (the cart dock) — replaces the per-tile buttons.
   Sits above the tab bar, appears only once something is selected.
   -------------------------------------------------------------------------- */
.market-cart-dock {
    position: fixed;
    left: 0;
    right: 0;
    margin-inline: auto;
    transform: none;
    bottom: calc(var(--safe-b) + var(--tabbar-h) + 18px);
    width: min(calc(100% - 32px), calc(var(--content-max) - 32px));
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 8px 8px 14px;
    border: 0;
    border-radius: var(--r-pill);
    background: var(--surface-1);
    box-shadow: 0 12px 40px rgba(0, 0, 0, .58);
    z-index: 41;
    animation: tier-dock-in var(--t-base) var(--e-out) both;
    transition: transform var(--t-fast) var(--e-out);
}

.market-cart-dock::before {
    display: none;
}

.market-cart-dock:active {
    transform: scale(.98);
}

@keyframes tier-dock-in {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* The old build hid this as screen-reader-only; the count is visible now, so
   the clip/1px cage has to be undone explicitly. */
.market-cart-dock-text {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip: auto;
    clip-path: none;
    white-space: normal;
    flex: 1;
    display: grid;
    gap: 1px;
    text-align: left;
    min-width: 0;
}

.market-cart-dock-text strong {
    font-size: 16px;
    line-height: 20px;
    font-weight: var(--w-semi);
    letter-spacing: -.01em;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}

.market-cart-dock-text small {
    font-size: 12px;
    line-height: 15px;
    font-weight: var(--w-reg);
    color: var(--ink-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.market-cart-dock-go {
    flex: none;
    min-height: 44px;
    display: grid;
    place-items: center;
    padding: 0 22px;
    border-radius: var(--r-pill);
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 15px;
    line-height: 18px;
    font-weight: var(--w-semi);
}

/* Overlapping preview discs of the most recent picks. */
.market-cart-dock-stack {
    flex: none;
    display: flex;
    align-items: center;
}

.market-cart-dock-thumb {
    width: 30px;
    height: 30px;
    border-radius: var(--r-pill);
    overflow: hidden;
    background: var(--surface-2);
    border: 1.5px solid #1b1b1d;
    display: grid;
    place-items: center;
}

.market-cart-dock-thumb + .market-cart-dock-thumb {
    margin-left: -10px;
}

.market-cart-dock-thumb.is-new {
    animation: tier-thumb-in var(--t-base) var(--e-out) both;
}

.market-cart-dock-thumb img {
    width: 78%;
    height: 78%;
    object-fit: contain;
}

@keyframes tier-thumb-in {
    from { opacity: 0; transform: scale(.4); }
    to   { opacity: 1; transform: scale(1); }
}

/* --------------------------------------------------------------------------
   Grouped list rows (sheets, settings)
   -------------------------------------------------------------------------- */
.ui-section.oem-sheet-section,
.market-builder-section,
.market-global-settings {
    border-radius: var(--r-lg);
    background: var(--surface-1);
    border: 1px solid var(--hairline);
    overflow: hidden;
    backdrop-filter: none;
}

/* Telegram/iOS cell: 16px leading pad, 52px min height, hairline separator
   drawn as a 0.33px box-shadow inset to the text column — matching the
   reference rather than a full-bleed 1px border. */
.ui-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 16px 6px var(--tg-row-pad);
    min-height: var(--tg-row-min);
    position: relative;
    transition: background var(--t-fast) var(--e-out);
}

.ui-card > .ui-row:not(:last-child)::after {
    content: "";
    position: absolute;
    left: var(--tg-row-pad);
    right: 0;
    bottom: 0;
    height: .33px;
    background: var(--tg-separator);
}

/* When a row leads with an icon the separator starts after it, iOS-style. */
.ui-card > .ui-row:not(:last-child):has(> .ui-row-before)::after {
    left: calc(var(--tg-row-pad) + var(--tg-icon) + 12px);
}

.ui-row + .ui-row::before {
    display: none;
}

.ui-row--interactive:active {
    background: rgba(255, 255, 255, .06);
}

/* --------------------------------------------------------------------------
   Sheets and modals
   -------------------------------------------------------------------------- */
.oem-sheet,
.ui-modal {
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    background: #141416;
    border: 1px solid var(--hairline);
    border-bottom: 0;
    backdrop-filter: none;
}

.ui-modal:not(.oem-sheet) {
    border-radius: var(--r-xl);
    border-bottom: 1px solid var(--hairline);
}

.ui-overlay {
    background: rgba(0, 0, 0, .62);
}

/* The per-emoji editor is now opened from inside the cart, so it has to sit
   above it — the cart overlay is z-index 110 and would otherwise bury it. */
#tileEditorOverlay {
    z-index: 130;
}

/* --------------------------------------------------------------------------
   Pack builder (cart sheet)
   Section headings become overlines; the group container stops being a card so
   the cards inside it aren't double-bordered.
   -------------------------------------------------------------------------- */
.market-builder-heading {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 0 4px 8px;
}

.market-builder-heading > span {
    font-size: 13px;
    line-height: 16px;
    font-weight: var(--w-semi);
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.market-builder-heading > small {
    font-size: 12px;
    line-height: 15px;
    font-weight: var(--w-reg);
    color: var(--ink-3);
    text-transform: none;
    letter-spacing: 0;
}

.market-builder-section {
    background: none;
    border: 0;
    border-radius: 0;
    overflow: visible;
    margin-bottom: 20px;
}

.market-global-settings {
    background: none;
    border: 0;
    border-radius: 0;
    overflow: visible;
}

.market-global-settings-intro {
    display: grid;
    gap: 3px;
    padding: 0 4px 14px;
}

.market-global-settings-intro > span {
    font-size: 17px;
    line-height: 22px;
    font-weight: var(--w-semi);
    letter-spacing: -.01em;
    color: var(--ink);
}

.market-global-settings-intro > small {
    font-size: 13px;
    line-height: 17px;
    color: var(--ink-3);
}

.ui-card.market-settings-card {
    border-radius: var(--r-lg);
    background: var(--surface-1);
    border: 1px solid var(--hairline);
}

/* Pack-type segmented control — same track/thumb language as the font one. */
.market-pack-type {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 2px;
    padding: 2px;
    border-radius: var(--r-sm);
    background: rgba(255, 255, 255, .07);
    border: 0;
    box-shadow: none;
}

.market-pack-type-button {
    border: 0;
    border-radius: 10px;
    padding: 10px 12px;
    background: none;
    box-shadow: none;
    color: var(--ink-2);
    font-size: 15px;
    line-height: 19px;
    font-weight: var(--w-med);
    transition: background var(--t-base) var(--e-out),
                color var(--t-base) var(--e-out);
}

.market-pack-type-button.is-active {
    background: var(--surface-3);
    color: var(--ink);
    font-weight: var(--w-semi);
}

.market-pack-type-hint {
    margin: 8px 4px 0;
    font-size: 13px;
    line-height: 17px;
    color: var(--ink-3);
}

.market-cart-sheet {
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    background: #141416;
    border: 1px solid var(--hairline);
    border-bottom: 0;
}

/* Pinned checkout bar: it sits over scrolling content at bottom:0, so it needs
   its own backdrop — without one the chat preview reads straight through it. */
.market-checkout-bar {
    background: linear-gradient(to top, #141416 62%, rgba(20, 20, 22, .92) 82%, rgba(20, 20, 22, 0));
    padding: 12px 16px calc(12px + var(--safe-b));
    box-sizing: border-box;
}

.market-cart-sheet::before {
    display: none;
}

.market-cart-header h2 {
    font-size: 17px;
    line-height: 22px;
    font-weight: var(--w-semi);
    letter-spacing: -.01em;
    margin: 0;
}

.market-kicker {
    font-size: 11px;
    line-height: 14px;
    font-weight: var(--w-semi);
    letter-spacing: .06em;
    color: var(--ink-3);
}

/* --------------------------------------------------------------------------
   Sheet chrome: handle, header, preview
   -------------------------------------------------------------------------- */
.oem-sheet-handle {
    width: 36px;
    height: 5px;
    margin: 8px auto 4px;
    border-radius: var(--r-pill);
    background: rgba(255, 255, 255, .22);
}

.oem-sheet-header {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 8px;
    padding: 8px 16px 16px;
}

.oem-sheet-header .ui-modal-title.oem-sheet-title {
    font-size: 17px;
    line-height: 22px;
    font-weight: var(--w-semi);
    letter-spacing: -.01em;
    text-align: center;
    margin: 0;
}

.oem-sheet-header-side {
    display: flex;
    justify-content: flex-start;
}

.oem-sheet-header-side--end {
    justify-content: flex-end;
}

.oem-sheet-text-btn {
    border: 0;
    background: none;
    padding: 4px 0;
    font-size: 16px;
    line-height: 20px;
    font-weight: var(--w-reg);
    color: var(--ink-2);
    transition: opacity var(--t-fast) var(--e-out);
}

.oem-sheet-text-btn--accent {
    color: var(--accent);
    font-weight: var(--w-semi);
}

.oem-sheet-text-btn:active {
    opacity: .55;
}

/* justify-items:center would shrink the preview to its content and make a
   percentage width resolve against nothing — it gets an explicit size. */
.oem-sheet-preview-section {
    display: flex;
    justify-content: center;
    margin-bottom: 24px;
}

.oem-sheet-preview {
    width: 216px;
    max-width: 62%;
    height: auto;
    flex: none;
    aspect-ratio: 1 / 1;
    display: grid;
    place-items: center;
    padding: 16px;
    border-radius: var(--r-lg);
    background: var(--surface-1);
    border: 1px solid var(--hairline);
}

.oem-sheet-preview > .oem-template-img,
.oem-sheet-preview > .oem-template-live {
    grid-area: 1 / 1;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.oem-sheet-body {
    padding: 0 16px 24px;
}

/* --------------------------------------------------------------------------
   Sheet interior: grouped cards, section headers, footers
   -------------------------------------------------------------------------- */
.ui-section.oem-sheet-section {
    background: none;
    border: 0;
    border-radius: 0;
    margin-bottom: 20px;
    overflow: visible;
}

.ui-card {
    border-radius: var(--r-lg);
    background: var(--surface-1);
    border: 1px solid var(--hairline);
    overflow: hidden;
}

/* A title-only row is a section header, not a list item. Two shapes exist: a
   bare row directly in the section, and one tucked at the top of a card. */
.oem-sheet-section > .ui-row .ui-row-title,
.oem-position-card > .ui-row:first-child .ui-row-title,
.oem-sheet-section > .ui-card > .ui-row:first-child:has(> .ui-row-body:only-child) .ui-row-title {
    font-size: 13px;
    line-height: 16px;
    font-weight: var(--w-semi);
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.oem-sheet-section > .ui-row {
    padding: 0 4px 8px;
    min-height: 0;
}

.oem-sheet-section > .ui-row::before {
    display: none;
}

.ui-section-footer {
    margin: 8px 4px 0;
    font-size: 13px;
    line-height: 17px;
    color: var(--ink-3);
}

.ui-row-before.oem-emoji {
    width: var(--tg-icon);
    height: var(--tg-icon);
    flex: none;
    border-radius: 10px;
    background: var(--surface-2);
    display: grid;
    place-items: center;
    color: var(--ink-2);
    overflow: hidden;
}

.ui-row-before.oem-emoji svg,
.ui-row-before.oem-emoji img {
    width: 22px;
    height: 22px;
}

.ui-row-body {
    flex: 1;
    display: grid;
    gap: 2px;
    min-width: 0;
}

.ui-row-after.oem-trailing {
    color: var(--ink-3);
    display: inline-flex;
}

/* --------------------------------------------------------------------------
   Segmented control — a track with a sliding thumb, not a pill inside a pill
   -------------------------------------------------------------------------- */
/* The sliding ::before thumb is the right mechanism — it is kept and restyled
   to the radius scale rather than replaced with per-button backgrounds. */
.oem-tile-segmented {
    height: 36px;
    margin: 0 16px 16px;
    padding: 2px;
    border-radius: var(--r-sm);
    background: rgba(255, 255, 255, .07);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border: 0;
    box-shadow: none;
}

.oem-tile-segmented::before {
    border-radius: 10px;
    background: var(--surface-3);
    box-shadow: none;
    transition: transform var(--t-base) var(--e-out);
}

.oem-tile-segment-btn {
    border-radius: 10px;
    background: none;
    box-shadow: none;
    color: var(--ink-2);
    font-size: 14px;
    line-height: 18px;
    font-weight: var(--w-med);
    transition: color var(--t-base) var(--e-out);
}

.oem-tile-segmented[data-active="montserrat"] .oem-tile-segment-btn[data-font="montserrat"],
.oem-tile-segmented[data-active="seymour"] .oem-tile-segment-btn[data-font="seymour"] {
    color: var(--ink);
    font-weight: var(--w-semi);
}

.oem-line-segmented {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 2px;
    padding: 2px;
    border-radius: var(--r-sm);
    background: rgba(255, 255, 255, .07);
    border: 0;
}

.oem-line-segmented::after {
    display: none;
}

.oem-line-segmented > button {
    border: 0;
    border-radius: 10px;
    padding: 8px 12px;
    background: none;
    color: var(--ink-2);
    font-size: 14px;
    line-height: 18px;
    font-weight: var(--w-med);
    transition: background var(--t-base) var(--e-out),
                color var(--t-base) var(--e-out);
}

.oem-line-segmented > button.is-active {
    background: var(--surface-3);
    color: var(--ink);
    font-weight: var(--w-semi);
}

/* --------------------------------------------------------------------------
   Hero — the headline sits inside the light, which is what gives the glow a
   job to do rather than leaving it as wallpaper.
   -------------------------------------------------------------------------- */
.tier-hero {
    display: grid;
    justify-items: center;
    padding: 18px 16px 26px;
}

.tier-hero__mark {
    height: 52px;
    width: auto;
}

/* In fullscreen the close/menu buttons float over the page — keep the mark
   clear of them. */
body.tier-fullscreen .tier-hero {
    padding-top: 26px;
}

/* Reference title1: 28/34, bold. */
.tier-hero__greeting {
    margin: 0;
    font-size: 28px;
    line-height: 34px;
    font-weight: var(--w-bold);
    letter-spacing: -.02em;
    color: var(--ink);
}

.tier-hero__sub {
    margin: 6px 0 0;
    font-size: 15px;
    line-height: 20px;
    font-weight: var(--w-reg);
    color: rgba(255, 255, 255, .66);
    max-width: 30ch;
}

/* --------------------------------------------------------------------------
   Section headers — reference "headline" style: full-strength text, sentence
   case, 8/16/12 padding. Not a grey uppercase overline.
   -------------------------------------------------------------------------- */
.market-tabs {
    display: flex;
    gap: 16px;
    margin: 0;
    padding: 8px 4px 12px;
}

.market-tabs .market-tab {
    font-size: 20px;
    line-height: 25px;
    font-weight: var(--w-bold);
    letter-spacing: -.01em;
    text-transform: none;
    color: var(--ink);
    background: none;
    border: 0;
    padding: 0;
    transition: opacity var(--t-fast) var(--e-out);
}

.market-tabs .market-tab:not(.is-active) {
    color: var(--ink-3);
    font-weight: var(--w-semi);
}

/* Admin-supplied promo art: it arrives at arbitrary dimensions, so it has to
   be cropped to the frame instead of being stretched into a seam. */
.market-hero-banner {
    width: 100%;
    margin: 0 0 8px;
    border-radius: var(--tg-radius);
    overflow: hidden;
    border: 0;
    box-shadow: none;
    aspect-ratio: 686 / 220;
}

.market-hero-banner-img,
.market-hero-banner svg {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.market-hero-banner::before,
.market-hero-banner::after {
    display: none;
}

/* --------------------------------------------------------------------------
   Empty states
   -------------------------------------------------------------------------- */
/* When the list holds an empty state it is not a card — drop the surface. */
.ui-card.tier-empty-host {
    background: none;
    border: 0;
}

.tier-empty {
    display: grid;
    justify-items: center;
    gap: 6px;
    padding: 48px 24px;
    text-align: center;
}

.tier-empty__icon {
    width: 56px;
    height: 56px;
    margin-bottom: 10px;
    border-radius: var(--r-md);
    display: grid;
    place-items: center;
    background: var(--surface-1);
    border: 1px solid var(--hairline);
    color: var(--ink-3);
}

.tier-empty__title {
    margin: 0;
    font-size: 17px;
    line-height: 22px;
    font-weight: var(--w-semi);
    color: var(--ink);
}

.tier-empty__body {
    margin: 0;
    font-size: 15px;
    line-height: 20px;
    color: var(--ink-3);
    max-width: 30ch;
}

.tier-empty__cta {
    margin-top: 18px;
    border: 0;
    border-radius: var(--r-pill);
    padding: 13px 24px;
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 15px;
    line-height: 18px;
    font-weight: var(--w-semi);
    transition: transform var(--t-fast) var(--e-out),
                filter var(--t-fast) var(--e-out);
}

.tier-empty__cta:active {
    transform: scale(.96);
    filter: brightness(1.12);
}

/* --------------------------------------------------------------------------
   Focus + reduced motion
   -------------------------------------------------------------------------- */
:where(button, a, input, [tabindex]):focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--r-xs);
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
}
