/* ============================================================
   CTExpertise — Design system
   ------------------------------------------------------------
   Single stylesheet for the whole front. Everything is built from
   the tokens in :root — never hardcode a colour, a radius or a
   spacing value in a page.

   Conventions:
     * block__element--modifier (BEM), lowercase, dash separated
     * layout components own their spacing, atoms never do
     * a component NEVER sets its own margin: the parent decides
       (use .u-stack / .u-grid on the container)

   Live catalogue of every component: /system-design (MODERATOR+)
   ============================================================ */

/* ============================================================
   1. Tokens
   ============================================================ */

:root {
    /* ---- Surfaces ---- */
    --c-bg: #0f1720;
    --c-panel: #141d29;
    --c-panel-2: #1b2635;
    --c-panel-3: #22303f;
    --c-border: #26313f;
    --c-border-strong: #35455a;

    /* ---- Text ---- */
    --c-text: #e8edf2;
    --c-muted: #8b98a8;
    --c-faint: #64707f;

    /* ---- Brand & semantics ---- */
    --c-accent: #ff8a00;
    --c-accent-hover: #ffa133;
    --c-accent-ink: #1a1208; /* text drawn ON the accent colour */
    --c-success: #2ecc71;
    --c-danger: #e74c3c;
    --c-warning: #f0b429;
    --c-info: #4aa3f0;

    /* Translucent fills: they sit on any surface without a second variable */
    --c-accent-soft: rgba(255, 138, 0, 0.14);
    --c-success-soft: rgba(46, 204, 113, 0.14);
    --c-danger-soft: rgba(231, 76, 60, 0.14);
    --c-warning-soft: rgba(240, 180, 41, 0.14);
    --c-info-soft: rgba(74, 163, 240, 0.14);

    /* Medal colours (leaderboard) */
    --c-gold: #ffd700;
    --c-silver: #c0c0c0;
    --c-bronze: #cd7f32;

    /* ---- Spacing scale (4px base) ---- */
    --sp-1: 4px;
    --sp-2: 8px;
    --sp-3: 12px;
    --sp-4: 16px;
    --sp-5: 20px;
    --sp-6: 24px;
    --sp-8: 32px;
    --sp-10: 40px;

    /* ---- Radii ---- */
    --r-sm: 6px;
    --r-md: 8px;
    --r-lg: 12px;
    --r-pill: 999px;

    /* ---- Typography ---- */
    --f-sans: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    --f-mono: ui-monospace, "Cascadia Code", Consolas, monospace;
    --fs-xs: 0.6875rem;  /* 11px — labels, legal */
    --fs-sm: 0.75rem;    /* 12px — meta */
    --fs-md: 0.8125rem;  /* 13px — secondary */
    --fs-base: 0.875rem; /* 14px — body */
    --fs-lg: 1rem;
    --fs-xl: 1.375rem;
    --fs-2xl: 1.75rem;
    --fw-regular: 400;
    --fw-semibold: 600;
    --fw-bold: 700;

    /* ---- Elevation & focus ---- */
    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-2: 0 8px 28px rgba(0, 0, 0, 0.45);
    --focus-ring: 2px solid var(--c-accent);

    /* ---- Layout ---- */
    --layout-max: 1280px;
    --sidebar-w: 220px;
    --rail-w: 280px;
    --z-modal: 100;
}

/* ============================================================
   2. Base
   ============================================================ */

*,
*::before,
*::after {
    box-sizing: border-box;
}

/* Column layout so a short page still pushes its footer to the bottom of the
   viewport. svh rather than vh: on mobile, vh includes the browser chrome and
   leaves the footer just below the fold. */
body {
    margin: 0;
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    background: var(--c-bg);
    color: var(--c-text);
    font-family: var(--f-sans);
    font-size: var(--fs-base);
    line-height: 1.5;
}

/* The footer slot (filled by Shell.mountFooter). The auto margin eats the free
   space above it on a short page, and collapses to nothing on a long one. */
.page-shell__footer {
    margin-top: auto;
}

a {
    color: inherit;
    text-decoration: none;
}

a:hover {
    color: var(--c-accent);
}

h1, h2, h3, h4 {
    margin: 0;
    line-height: 1.25;
}

h1 { font-size: var(--fs-2xl); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); }
h4 { font-size: var(--fs-base); }

p { margin: 0 0 var(--sp-3); }

p:last-child { margin-bottom: 0; }

hr {
    border: none;
    border-top: 1px solid var(--c-border);
    margin: var(--sp-4) 0;
}

/* Keyboard focus only: a mouse click must not draw the ring */
:focus-visible {
    outline: var(--focus-ring);
    outline-offset: 2px;
}

[hidden] { display: none !important; }

/* ============================================================
   3. Layout
   ============================================================ */

/* Three-column shell: sidebar / main / rail. Columns collapse away
   on narrow screens instead of squeezing the main content. */
.layout {
    display: flex;
    gap: var(--sp-4);
    max-width: var(--layout-max);
    margin: 0 auto;
    padding: var(--sp-4);
    align-items: flex-start;
}

/* align-items: flex-start above is meant for the three-column shell (a sticky
   sidebar must not stretch). In the single-column variants it would leave every
   child at its natural width -- a grid then collapses to one item per row. */
.layout--centered,
.layout--narrow,
.layout--reading {
    flex-direction: column;
    align-items: stretch;
}

.layout--centered { max-width: 960px; }

.layout--narrow { max-width: 620px; }

.layout--reading { max-width: 820px; }

.layout__sidebar {
    width: var(--sidebar-w);
    flex-shrink: 0;
    position: sticky;
    top: var(--sp-4);
}

.layout__main {
    flex: 1;
    min-width: 0; /* lets long words wrap instead of blowing the layout */
}

.layout__rail {
    width: var(--rail-w);
    flex-shrink: 0;
}

@media (max-width: 1080px) {
    .layout__rail { display: none; }
}

@media (max-width: 860px) {
    .layout { flex-direction: column; }
    .layout__sidebar { width: 100%; position: static; }
}

/* Vertical rhythm helper: the container spaces its children, so
   no component needs a margin of its own. */
.u-stack > * + * { margin-top: var(--sp-3); }
.u-stack--lg > * + * { margin-top: var(--sp-5); }

/* A slot a script left empty (a section that does not apply to this role)
   must not keep taking a gap in the stack. */
.u-stack > :empty,
.u-stack--lg > :empty { display: none; }

/* ============================================================
   4. Topbar & navigation
   ============================================================ */

/* Wraps by default: its content is role-dependent (a moderator gets one more
   tab, a long display name a wider chip). Without wrapping, the extra items
   push the bar past the viewport and give the WHOLE page a horizontal scroll. */
.topbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    row-gap: var(--sp-2);
    column-gap: var(--sp-5);
    padding: var(--sp-2) var(--sp-5);
    background: var(--c-panel);
    border-bottom: 1px solid var(--c-border);
    position: sticky;
    top: 0;
    z-index: 10;
}

.topbar__brand {
    font-size: 1.25rem;
    font-weight: var(--fw-bold);
    color: var(--c-accent);
    white-space: nowrap;
}

.topbar__brand:hover { color: var(--c-accent-hover); }

.topbar__brand span { color: var(--c-text); }

.topbar__spacer { flex: 1; }

.mainnav {
    display: flex;
    gap: var(--sp-4);
    font-size: var(--fs-base);
}

.mainnav__link {
    padding: var(--sp-1) var(--sp-1);
    color: var(--c-muted);
    border-bottom: 2px solid transparent;
    white-space: nowrap;
}

.mainnav__link:hover,
.mainnav__link--active {
    color: var(--c-text);
    border-bottom-color: var(--c-accent);
}

.searchbar {
    flex: 1;
    max-width: 320px;
    min-width: 120px;
}

.searchbar__input {
    width: 100%;
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--c-border);
    border-radius: var(--r-pill);
    background: var(--c-panel-2);
    color: var(--c-text);
    font: inherit;
}

.topbar__actions {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--fs-md);
}

/* Wallet balance pill in the topbar */
.balance {
    padding: var(--sp-1) var(--sp-3);
    border: 1px solid var(--c-border);
    border-radius: var(--r-pill);
    background: var(--c-panel-2);
    white-space: nowrap;
}

.balance--empty { color: var(--c-muted); }

.user-chip {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    color: var(--c-muted);
    font-size: var(--fs-md);
    white-space: nowrap;
}

@media (max-width: 860px) {
    .topbar { column-gap: var(--sp-3); }
    /* Narrow screens: the search takes a line of its own rather than being
       squeezed between the brand and the account chip. */
    .searchbar { order: 10; max-width: none; flex-basis: 100%; }
}

/* ============================================================
   5. Sidebar (filters)
   ============================================================ */

.filter-group + .filter-group { margin-top: var(--sp-5); }

.filter-group__title {
    font-size: var(--fs-sm);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--c-muted);
    margin-bottom: var(--sp-2);
}

.filter-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.filter-list__item {
    display: block;
    width: 100%;
    text-align: left;
    padding: var(--sp-1) var(--sp-2);
    border: none;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--c-muted);
    font: inherit;
    cursor: pointer;
}

.filter-list__item:hover,
.filter-list__item--active {
    background: var(--c-panel-2);
    color: var(--c-text);
}

/* ============================================================
   6. Buttons
   ============================================================ */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-4);
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    font: inherit;
    font-weight: var(--fw-semibold);
    line-height: 1.4;
    cursor: pointer;
    white-space: nowrap;
    background: var(--c-panel-2);
    color: var(--c-text);
}

.btn:hover { color: var(--c-text); }

.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn--accent {
    background: var(--c-accent);
    color: var(--c-accent-ink);
}

.btn--accent:hover:not(:disabled) {
    background: var(--c-accent-hover);
    color: var(--c-accent-ink);
}

.btn--success {
    background: var(--c-success);
    color: #08160e;
}

.btn--outline {
    background: transparent;
    border-color: var(--c-border-strong);
    color: var(--c-text);
}

.btn--outline:hover:not(:disabled) { background: var(--c-panel-2); }

.btn--ghost {
    background: transparent;
    color: var(--c-muted);
}

.btn--ghost:hover:not(:disabled) { color: var(--c-text); }

.btn--danger {
    background: transparent;
    border-color: var(--c-danger);
    color: var(--c-danger);
}

.btn--danger:hover:not(:disabled) { background: var(--c-danger-soft); }

.btn--sm {
    padding: var(--sp-1) var(--sp-3);
    font-size: var(--fs-md);
}

.btn--block {
    display: flex;
    width: 100%;
}

/* Google sign-in keeps a neutral surface: brand guidelines forbid tinting it */
.btn--google {
    display: flex;
    width: 100%;
    background: var(--c-panel-2);
    border-color: var(--c-border-strong);
}

.btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
}

/* ============================================================
   7. Forms
   ============================================================ */

.form-row { margin-bottom: var(--sp-4); }

.form-row > label,
.form-label {
    display: block;
    font-size: var(--fs-sm);
    color: var(--c-muted);
    margin-bottom: var(--sp-1);
}

.form-row input,
.form-row select,
.form-row textarea,
.input {
    width: 100%;
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--c-border);
    border-radius: var(--r-sm);
    background: var(--c-panel-2);
    color: var(--c-text);
    font: inherit;
}

.form-row textarea { resize: vertical; min-height: 90px; }

.form-row input:focus,
.form-row select:focus,
.form-row textarea:focus {
    outline: var(--focus-ring);
    outline-offset: -1px;
}

.form-row input:disabled,
.form-row select:disabled,
.form-row textarea:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.form-hint {
    font-size: var(--fs-sm);
    color: var(--c-muted);
    margin: var(--sp-1) 0 0;
}

/* Reserves its line height so the layout does not jump when an error appears */
.field-error {
    color: var(--c-danger);
    font-size: var(--fs-sm);
    min-height: 1.1em;
    margin: var(--sp-1) 0 0;
}

.checkbox-row {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--fs-md);
    margin: var(--sp-2) 0;
}

.checkbox-row input { width: auto; }

.checkbox-row label { margin: 0; color: var(--c-text); }

fieldset {
    border: 1px solid var(--c-border);
    border-radius: var(--r-sm);
    padding: var(--sp-3);
    margin: 0 0 var(--sp-4);
}

legend {
    font-size: var(--fs-sm);
    color: var(--c-muted);
    padding: 0 var(--sp-2);
}

.divider {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    color: var(--c-muted);
    font-size: var(--fs-sm);
    margin: var(--sp-5) 0;
}

.divider::before,
.divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--c-border);
}

/* ============================================================
   8. Cards & rows
   ============================================================ */

.card {
    background: var(--c-panel);
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    overflow: hidden;
}

.card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    background: var(--c-panel-2);
    font-size: var(--fs-md);
    color: var(--c-muted);
}

.card__header strong { color: var(--c-text); }

.card__body { padding: var(--sp-4); }

.card--narrow {
    max-width: 420px;
    margin: var(--sp-10) auto;
}

/* Generic list row. Used for matches, analyses, transactions, accounts:
   one component instead of one per screen. */
.row {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-top: 1px solid var(--c-border);
}

.row:first-child { border-top: none; }

.row--link { cursor: pointer; width: 100%; text-align: left; background: none; border-left: none; border-right: none; border-bottom: none; font: inherit; color: inherit; }

.row--link:hover { background: var(--c-panel-2); }

.row--flush { border-top: none; padding-left: 0; padding-right: 0; }

.row__main { flex: 1; min-width: 0; }

.row__title { font-weight: var(--fw-semibold); }

.row__sub {
    font-size: var(--fs-sm);
    color: var(--c-muted);
    margin-top: 2px;
}

.price {
    font-weight: var(--fw-bold);
    color: var(--c-accent);
    white-space: nowrap;
}

.price--free { color: var(--c-success); }

/* ============================================================
   9. Tags & badges
   ============================================================ */

.tag {
    display: inline-block;
    padding: 2px var(--sp-2);
    border: 1px solid var(--c-border);
    border-radius: var(--r-pill);
    background: var(--c-panel-2);
    color: var(--c-muted);
    font-size: var(--fs-xs);
    white-space: nowrap;
}

.tag--success { background: var(--c-success-soft); color: var(--c-success); border-color: var(--c-success); }
.tag--danger  { background: var(--c-danger-soft);  color: var(--c-danger);  border-color: var(--c-danger); }
.tag--warning { background: var(--c-warning-soft); color: var(--c-warning); border-color: var(--c-warning); }
.tag--info    { background: var(--c-info-soft);    color: var(--c-info);    border-color: var(--c-info); }
.tag--accent  { background: var(--c-accent-soft);  color: var(--c-accent);  border-color: var(--c-accent); }

.badge {
    display: inline-block;
    padding: 2px var(--sp-3);
    border-radius: var(--r-pill);
    background: var(--c-panel-3);
    color: var(--c-muted);
    font-size: var(--fs-xs);
    font-weight: var(--fw-semibold);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.badge--seller    { background: var(--c-accent-soft);  color: var(--c-accent); }
.badge--moderator { background: var(--c-success-soft); color: var(--c-success); }
.badge--admin     { background: var(--c-danger-soft);  color: var(--c-danger); }

/* ============================================================
   10. Stats
   ============================================================ */

/* Three columns, whatever the number of tiles: a fixed rhythm reads better
   than auto-fit, which reflows the whole block as soon as one tile is added.
   minmax(0, 1fr) rather than 1fr so a long value cannot widen its column. */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-3);
}

@media (max-width: 720px) {
    .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 420px) {
    .stats-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Free-flowing grid, for collections whose count is not a design decision
   (the token swatches of /system-design). */
.token-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: var(--sp-3);
}

.stat-box {
    background: var(--c-panel);
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    padding: var(--sp-4);
    text-align: center;
}

.stat-box__value {
    font-size: var(--fs-xl);
    font-weight: var(--fw-bold);
    color: var(--c-accent);
}

.stat-box__value--lg { font-size: var(--fs-2xl); }

.stat-box__label {
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--c-muted);
    margin-top: var(--sp-1);
}

/* ============================================================
   11. Table
   ============================================================ */

.table-wrap { overflow-x: auto; }

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-base);
}

.table th,
.table td {
    text-align: left;
    padding: var(--sp-3);
    border-top: 1px solid var(--c-border);
}

.table thead th {
    border-top: none;
    color: var(--c-muted);
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.table tbody tr:hover { background: var(--c-panel-2); }

.table__num { text-align: right; font-variant-numeric: tabular-nums; }

.rank { font-weight: var(--fw-bold); }
.rank--1 { color: var(--c-gold); }
.rank--2 { color: var(--c-silver); }
.rank--3 { color: var(--c-bronze); }

/* ============================================================
   12. Avatar & profile header
   ============================================================ */

.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 80px;
    height: 80px;
    flex-shrink: 0;
    border: 2px solid var(--c-accent);
    border-radius: 50%;
    background: var(--c-panel-2);
    color: var(--c-accent);
    font-size: 1.75rem;
    font-weight: var(--fw-bold);
}

.avatar--sm { width: 32px; height: 32px; font-size: var(--fs-md); border-width: 1px; }
.avatar--md { width: 44px; height: 44px; font-size: var(--fs-lg); }

.profile-header {
    display: flex;
    align-items: center;
    gap: var(--sp-5);
    padding: var(--sp-5);
    background: var(--c-panel);
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
}

.profile-header__body { flex: 1; min-width: 0; }

.author {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
}

/* ============================================================
   13. Paywall
   ============================================================ */

/* Preview and overlay share ONE grid cell, so the block is always as tall as
   the taller of the two. With an absolutely positioned overlay, a short teaser
   made the lock and its button spill out of the card. */
.locked {
    display: grid;
}

.locked > * {
    grid-area: 1 / 1;
}

/* The blurred text is decorative only — the API never sends the premium
   content to an account without access, so there is nothing to un-blur. */
.locked__preview {
    filter: blur(6px);
    user-select: none;
    pointer-events: none;
}

.locked__overlay {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--sp-3);
    padding: var(--sp-5) var(--sp-4);
    text-align: center;
    background: rgba(15, 23, 32, 0.62);
}

.locked__icon { font-size: 2rem; }

/* ============================================================
   14. Alerts & notices
   ============================================================ */

.alert {
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--c-accent);
    border-radius: var(--r-sm);
    background: var(--c-accent-soft);
    color: var(--c-accent);
    font-size: var(--fs-md);
}

.alert--error   { border-color: var(--c-danger);  background: var(--c-danger-soft);  color: var(--c-danger); }
.alert--success { border-color: var(--c-success); background: var(--c-success-soft); color: var(--c-success); }
.alert--info    { border-color: var(--c-info);    background: var(--c-info-soft);    color: var(--c-info); }

/* ============================================================
   15. Modal
   ============================================================ */

.modal {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: var(--sp-6) var(--sp-4);
    overflow: auto;
    background: rgba(0, 0, 0, 0.55);
}

.modal__dialog {
    width: 100%;
    max-width: 640px;
    background: var(--c-panel);
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-2);
}

.modal__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: var(--sp-4);
    border-bottom: 1px solid var(--c-border);
}

.modal__body { padding: var(--sp-4); }

.modal__footer {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    padding: var(--sp-4);
    border-top: 1px solid var(--c-border);
}

/* ============================================================
   16. Empty state, skeleton, prose
   ============================================================ */

.empty {
    padding: var(--sp-8) var(--sp-4);
    text-align: center;
    color: var(--c-muted);
    font-size: var(--fs-md);
}

/* Placeholder shown while a request is in flight, so the page does not
   flash from blank to full. */
.skeleton {
    height: 14px;
    border-radius: var(--r-sm);
    background: linear-gradient(90deg, var(--c-panel-2) 25%, var(--c-panel-3) 50%, var(--c-panel-2) 75%);
    background-size: 200% 100%;
    animation: skeleton-shimmer 1.2s ease-in-out infinite;
}

.skeleton--row { height: 44px; }

@keyframes skeleton-shimmer {
    from { background-position: 200% 0; }
    to { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .skeleton { animation: none; }
}

/* Long user-written text (analysis content). Rendered with textContent,
   never innerHTML, so newlines must be preserved by CSS. */
.prose {
    white-space: pre-wrap;
    word-break: break-word;
    font-family: inherit;
    font-size: var(--fs-base);
    line-height: 1.65;
    margin: 0;
}

/* ============================================================
   17. Footer
   ============================================================ */

.page-footer {
    margin-top: var(--sp-8);
    padding: var(--sp-5);
    border-top: 1px solid var(--c-border);
    text-align: center;
    color: var(--c-muted);
    font-size: var(--fs-sm);
}

.disclaimer {
    max-width: var(--layout-max);
    margin: 0 auto;
    padding: 0 var(--sp-4);
    color: var(--c-faint);
    font-size: var(--fs-xs);
}

/* ============================================================
   18. Utilities
   ------------------------------------------------------------
   Deliberately few: a utility exists only when the same one-off
   declaration would otherwise be repeated across pages.
   ============================================================ */

.u-muted { color: var(--c-muted); }
.u-small { font-size: var(--fs-sm); }
.u-center { text-align: center; }
.u-right { text-align: right; }
.u-flex { display: flex; align-items: center; gap: var(--sp-2); }
.u-between { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.u-wrap { flex-wrap: wrap; }
.u-grow { flex: 1; min-width: 0; }
.u-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.u-nowrap { white-space: nowrap; }
