/* ==========================================================================
   Kratefast UI
   A precision-tool interface: neutral surfaces, one monochrome accent taken
   from the brand mark, monospace for machine output (URLs, counts) and sans
   for human language.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
    color-scheme: light;

    /* Neutrals -- cool slate ramp */
    --c-canvas: #f6f7f9;
    --c-surface: #ffffff;
    --c-surface-2: #f1f3f6;
    --c-surface-3: #e7eaef;
    --c-border: #dfe3e9;
    /* Component boundaries that identify an interactive control must clear
       3:1 against their surface (WCAG 1.4.11). */
    --c-border-strong: #7d8796;
    --c-text: #16191f;
    --c-text-2: #4a515c;
    --c-text-3: #656d78;

    /* Accent -- monochrome, sampled from the brand mark: its darkest grey
       (#323232) on light surfaces, its lightest (#e5e7eb) on dark ones. */
    --c-accent: #323232;
    --c-accent-hover: #1e1e1e;
    --c-accent-fg: #ffffff;
    --c-accent-soft: #e8eaed;
    --c-accent-border: #5a616b;
    --c-focus: #323232;

    /* Status */
    --c-danger: #b42318;
    --c-danger-soft: #fef3f2;
    --c-danger-border: #f3c4bf;

    /* Elevation */
    --shadow-1: 0 1px 2px rgba(16, 24, 40, 0.05);
    --shadow-2: 0 4px 14px rgba(16, 24, 40, 0.08);

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

    /* Borders */
    --hairline: 1px;

    /* Spacing */
    --sp-1: 0.25rem;
    --sp-2: 0.5rem;
    --sp-3: 0.75rem;
    --sp-4: 1rem;
    --sp-5: 1.25rem;
    --sp-6: 1.5rem;
    --sp-8: 2rem;
    --sp-10: 2.5rem;
    --sp-12: 3rem;

    /* Type */
    --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
        "Liberation Mono", monospace;

    --text-xs: 0.75rem;
    --text-sm: 0.8125rem;
    --text-md: 0.875rem;
    --text-lg: 1rem;
    --text-xl: 1.25rem;
    --text-2xl: 1.75rem;
    --text-3xl: 2.25rem;

    /* Motion */
    --dur: 160ms;
    --ease: cubic-bezier(0.2, 0.6, 0.3, 1);

    /* Layout */
    --page-max: 76rem;
    /* Width of the centred hero (headline, lede and search card) so their
       left and right edges line up exactly. */
    --hero-max: 42rem;
}

[data-theme="dark"] {
    color-scheme: dark;

    --c-canvas: #0c0f14;
    --c-surface: #141820;
    --c-surface-2: #1b2029;
    --c-surface-3: #242a34;
    --c-border: #262c37;
    --c-border-strong: #6b7686;
    --c-text: #e8ebf0;
    --c-text-2: #aab3c0;
    --c-text-3: #8b95a4;

    --c-accent: #e5e7eb;
    --c-accent-hover: #f3f4f6;
    --c-accent-fg: #0c0f14;
    --c-accent-soft: #262b34;
    --c-accent-border: #7d8695;
    --c-focus: #e5e7eb;

    --c-danger: #fda29b;
    --c-danger-soft: #2a1614;
    --c-danger-border: #5a2a26;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.45);
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */

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

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--c-canvas);
    color: var(--c-text);
    font-family: var(--font-sans);
    font-size: var(--text-md);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
p,
ul,
ol,
figure {
    margin: 0;
}

ul,
ol {
    padding: 0;
    list-style: none;
}

a {
    color: var(--c-accent);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

button,
input {
    font: inherit;
    color: inherit;
}

/* The user-agent rule for [hidden] is `display: none`, which any
   component-level `display` rule silently overrides.  Make it
   authoritative so `hidden` always means hidden. */
[hidden] {
    display: none !important;
}

:focus-visible {
    outline: 2px solid var(--c-focus);
    outline-offset: 2px;
    border-radius: var(--r-sm);
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: absolute;
    left: var(--sp-4);
    top: -4rem;
    z-index: 100;
    padding: var(--sp-2) var(--sp-4);
    background: var(--c-accent);
    color: var(--c-accent-fg);
    border-radius: var(--r-sm);
    font-weight: 600;
    transition: top var(--dur) var(--ease);
}

.skip-link:focus {
    top: var(--sp-4);
    text-decoration: none;
}

/* --------------------------------------------------------------------------
   3. Top bar
   -------------------------------------------------------------------------- */

.topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    background: color-mix(in srgb, var(--c-canvas) 88%, transparent);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--c-border);
}

/* Three equal tracks so the brand can sit dead-centre in the viewport while
   the theme toggle stays pinned to the right edge. */
.topbar__inner {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: var(--sp-3) var(--sp-6);
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: var(--sp-4);
}

.brand {
    grid-column: 2;
    justify-self: center;
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    color: var(--c-text);
    font-weight: 650;
    letter-spacing: -0.01em;
    /* Allows the track to shrink below the wordmark's intrinsic width so the
       topbar never overflows at extreme zoom levels (e.g. 200% on a phone). */
    min-width: 0;
}

.brand:hover {
    text-decoration: none;
}

/* The brand mark is a raster PNG whose alpha channel already carries the
   squircle's own corner radius, so no border-radius is applied here --
   clipping it would flatten the mark's shape. */
.brand__mark {
    display: block;
    flex: none;
    width: 1.75rem;
    height: 1.75rem;
}

/* On dark headers the mark's own dark rim disappears into the canvas, so a
   faint ring keeps its edge defined. */
[data-theme="dark"] .brand__mark {
    box-shadow: 0 0 0 1px var(--c-border-strong);
}

.brand__name {
    font-size: var(--text-lg);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   4. Buttons & controls
   -------------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    padding: 0.5rem 0.9rem;
    border: 1px solid transparent;
    border-radius: var(--r-md);
    background: transparent;
    font-size: var(--text-md);
    font-weight: 550;
    line-height: 1.4;
    cursor: pointer;
    white-space: nowrap;
    transition:
        background-color var(--dur) var(--ease),
        border-color var(--dur) var(--ease),
        color var(--dur) var(--ease);
}

.btn--primary {
    background: var(--c-accent);
    color: var(--c-accent-fg);
    border-color: var(--c-accent);
    box-shadow: var(--shadow-1);
}

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

.btn--ghost {
    border-color: var(--c-border-strong);
    color: var(--c-text-2);
}

.btn--ghost:hover:not(:disabled) {
    background: var(--c-surface-2);
    color: var(--c-text);
    border-color: var(--c-text-3);
}

.btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.icon-btn {
    grid-column: 3;
    justify-self: end;
    display: inline-grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--c-text-3);
    cursor: pointer;
    transition:
        background-color var(--dur) var(--ease),
        color var(--dur) var(--ease);
}

.icon-btn:hover {
    background: var(--c-surface-3);
    color: var(--c-text);
}

.icon-btn--sm {
    width: 1.75rem;
    height: 1.75rem;
}

.icon-btn svg {
    width: 1rem;
    height: 1rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* --------------------------------------------------------------------------
   5. Page layout
   -------------------------------------------------------------------------- */

.page {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: var(--sp-10) var(--sp-6) var(--sp-12);
    display: flex;
    flex-direction: column;
    gap: var(--sp-8);
}

.intro {
    width: 100%;
    max-width: var(--hero-max);
    margin-inline: auto;
    text-align: center;
}

.intro__title {
    font-size: var(--text-3xl);
    line-height: 1.15;
    letter-spacing: -0.025em;
    font-weight: 680;
    text-wrap: balance;
}

.intro__lede {
    margin-top: var(--sp-3);
    color: var(--c-text-2);
    font-size: var(--text-lg);
    text-wrap: balance;
}

/* --------------------------------------------------------------------------
   6. Search panel
   -------------------------------------------------------------------------- */

.search {
    align-self: center;
    width: 100%;
    max-width: var(--hero-max);
    background: var(--c-surface);
    border: var(--hairline) solid var(--c-border);
    border-radius: var(--r-lg);
    padding: var(--sp-6);
    box-shadow: var(--shadow-1);
}

.search__form {
    display: flex;
    align-items: flex-end;
    gap: var(--sp-3);
    flex-wrap: wrap;
}

.field {
    flex: 1 1 18rem;
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
    min-width: 0;
}

.field__label {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--c-text-2);
}

.field__input {
    width: 100%;
    padding: 0.6rem 0.75rem;
    background: var(--c-surface);
    border: 1px solid var(--c-border-strong);
    border-radius: var(--r-md);
    font-size: var(--text-lg);
    transition:
        border-color var(--dur) var(--ease),
        box-shadow var(--dur) var(--ease);
}

.field__input::placeholder {
    color: var(--c-text-3);
}

.field__input:hover {
    border-color: var(--c-text-3);
}

.field__input:focus {
    outline: none;
    border-color: var(--c-accent);
    box-shadow: 0 0 0 3px var(--c-accent-soft);
}

.search__btn {
    flex: 0 0 auto;
    padding: 0.6rem 1.1rem;
    font-size: var(--text-lg);
}

.search__meta {
    margin-top: var(--sp-4);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2) var(--sp-4);
    color: var(--c-text-3);
    font-size: var(--text-sm);
}

.search__meta kbd {
    padding: 0.05rem 0.35rem;
    border: 1px solid var(--c-border-strong);
    border-bottom-width: 2px;
    border-radius: var(--r-sm);
    background: var(--c-surface-2);
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    color: var(--c-text-2);
}

.dot-sep::before {
    content: "·";
    margin-right: var(--sp-4);
    color: var(--c-border-strong);
}

/* Recent searches */

.recent {
    margin-top: var(--sp-5);
    padding-top: var(--sp-4);
    border-top: 1px solid var(--c-border);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--sp-2);
}

.recent__label {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--c-text-3);
    margin-right: var(--sp-1);
}

.chip {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.6rem;
    border: 1px solid var(--c-border-strong);
    border-radius: var(--r-pill);
    background: var(--c-surface-2);
    color: var(--c-text-2);
    font-size: var(--text-sm);
    cursor: pointer;
    transition:
        background-color var(--dur) var(--ease),
        color var(--dur) var(--ease),
        border-color var(--dur) var(--ease);
}

.chip:hover {
    background: var(--c-accent-soft);
    border-color: var(--c-accent-border);
    color: var(--c-text);
}

/* --------------------------------------------------------------------------
   7. Progress panel
   -------------------------------------------------------------------------- */

/* The progress panel belongs to the search above it, so it keeps the same
   width and centring rather than stretching across the whole page. */
.progress {
    align-self: center;
    width: 100%;
    max-width: var(--hero-max);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    padding: var(--sp-5) var(--sp-6);
    box-shadow: var(--shadow-1);
}

.progress__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-4);
    flex-wrap: wrap;
}

.progress__title {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: -0.01em;
}

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

.progress__elapsed {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    color: var(--c-text-3);
    font-variant-numeric: tabular-nums;
}

.progress__bar {
    margin-top: var(--sp-4);
    height: 6px;
    border-radius: var(--r-pill);
    background: var(--c-surface-3);
    overflow: hidden;
}

.progress__fill {
    height: 100%;
    width: 0%;
    border-radius: inherit;
    background: var(--c-accent);
    transition: width 400ms var(--ease);
}

.progress__note {
    margin-top: var(--sp-4);
    color: var(--c-text-3);
    font-size: var(--text-sm);
}

.spinner {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    border: 2px solid var(--c-border-strong);
    border-top-color: var(--c-accent);
    border-radius: 50%;
    animation: spin 800ms linear infinite;
    flex: none;
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

/* Platform status pills */

.pills {
    margin-top: var(--sp-4);
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
}

.pill {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    padding: 0.2rem 0.6rem 0.2rem 0.5rem;
    border: 1px solid var(--c-border);
    border-radius: var(--r-pill);
    background: var(--c-surface-2);
    font-size: var(--text-sm);
    color: var(--c-text-3);
}

.pill__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--c-border-strong);
    flex: none;
}

.pill--active {
    border-color: var(--c-accent-border);
    background: var(--c-accent-soft);
    color: var(--c-text);
}

.pill--active .pill__dot {
    background: var(--c-accent);
    animation: pulse 1.2s ease-in-out infinite;
}

/* The muted tone does not clear 4.5:1 on the active pill's wash, so the
   running count steps up to the secondary tone instead. */
.pill--active .pill__count {
    color: var(--c-text-2);
}

.pill--done {
    color: var(--c-text-2);
}

.pill--done .pill__dot {
    background: var(--c-accent);
}

.pill__count {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--c-text-3);
    font-variant-numeric: tabular-nums;
}

@keyframes pulse {
    0%,
    100% {
        opacity: 1;
    }
    50% {
        opacity: 0.3;
    }
}

/* --------------------------------------------------------------------------
   8. Results
   -------------------------------------------------------------------------- */

/* The results block sits directly under the search card, so it shares the
   card's outer width AND its inner padding. That puts the heading, the
   summary, the filter field and the action buttons on exactly the same two
   vertical lines as the search input and the "Find mentions" button. */
.results {
    align-self: center;
    width: 100%;
    max-width: var(--hero-max);
    padding-inline: calc(var(--sp-6) + var(--hairline));
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
}

.results__head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--sp-4);
    flex-wrap: wrap;
}

.results__title {
    font-size: var(--text-2xl);
    letter-spacing: -0.02em;
    font-weight: 650;
}

.results__summary {
    margin-top: var(--sp-1);
    color: var(--c-text-2);
    font-size: var(--text-md);
}

.results__summary strong {
    font-family: var(--font-mono);
    font-weight: 600;
    color: var(--c-text);
    font-variant-numeric: tabular-nums;
}

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

.results__filter {
    max-width: 24rem;
    /* .results is a column flex container, so a rem-based flex-basis would
       size the filter's HEIGHT, not its width -- 256px of empty space under
       the input. Size it to its content; max-width still caps the width. */
    flex: 0 0 auto;
}

.results__filter .field__input {
    padding: 0.45rem 0.75rem;
    /* 16px, not 14px: iOS Safari zooms the viewport in when an input's
       font-size is below 16px, which breaks the layout on focus. */
    font-size: var(--text-lg);
}

.grid {
    display: grid;
    /* 17rem keeps two platform cards per row inside the 42rem content column
       (the results block is inset to line up with the search field). */
    grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
    gap: var(--sp-4);
    align-items: start;
}

/* --------------------------------------------------------------------------
   9. Platform card
   -------------------------------------------------------------------------- */

.card {
    --brand: var(--c-text-3);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-1);
    overflow: hidden;
    transition: border-color var(--dur) var(--ease);
}

.card:focus-within {
    border-color: var(--c-accent-border);
}

.card[data-platform="twitter"] { --brand: #1d9bf0; }
.card[data-platform="instagram"] { --brand: #e4405f; }
.card[data-platform="tiktok"] { --brand: #25f4ee; }
.card[data-platform="reddit"] { --brand: #ff4500; }
.card[data-platform="youtube"] { --brand: #ff0033; }
.card[data-platform="linkedin"] { --brand: #0a66c2; }
.card[data-platform="facebook"] { --brand: #1877f2; }
.card[data-platform="pinterest"] { --brand: #e60023; }
.card[data-platform="snapchat"] { --brand: #f7c948; }
.card[data-platform="threads"] { --brand: #7b7b7b; }

.card__head {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--c-border);
    background: var(--c-surface);
}

/* Inline icon sprite: present for <use> lookups, never painted. */
.icon-sprite {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.badge {
    display: grid;
    place-items: center;
    width: 1.625rem;
    height: 1.625rem;
    flex: none;
    border-radius: var(--r-sm);
    background: color-mix(in oklab, var(--brand) 16%, var(--c-surface));
    color: color-mix(in oklab, var(--brand) 52%, var(--c-text));
    box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--brand) 32%, transparent);
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

/* The mark inherits the badge's brand-tinted colour, so it earns the same
   audited contrast as the letter it replaced. */
.badge__mark {
    display: block;
    width: 1rem;
    height: 1rem;
    fill: currentColor;
}

/* TikTok's cyan is nearly white, so the standard brand mix leaves its mark
   washed out on a light chip (4.31:1). Pull that one closer to the text
   colour; every other platform clears 4.5:1 on the default mix. */
[data-theme="light"] .card[data-platform="tiktok"] .badge {
    color: color-mix(in oklab, var(--brand) 30%, var(--c-text));
}

.card__title {
    font-size: var(--text-md);
    font-weight: 600;
    letter-spacing: -0.005em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.card__count {
    margin-left: auto;
    padding: 0.05rem 0.4rem;
    border-radius: var(--r-pill);
    background: var(--c-surface-3);
    color: var(--c-text-2);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
}

.card__copy {
    flex: none;
}

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

.card__empty {
    padding: var(--sp-4);
    color: var(--c-text-3);
    font-size: var(--text-sm);
    text-align: center;
}

/* URL rows */

.urls {
    display: flex;
    flex-direction: column;
}

.url-row {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding: var(--sp-2);
    border-radius: var(--r-sm);
    transition: background-color var(--dur) var(--ease);
}

.url-row:hover {
    background: var(--c-surface-2);
}

.url-row__link {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: baseline;
    gap: var(--sp-2);
    color: var(--c-text);
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    line-height: 1.45;
}

/* A monochrome accent cannot signal hover through hue alone, so the link
   underlines instead -- the conventional affordance for a URL list. */
.url-row__link:hover {
    color: var(--c-text);
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
}

.url-row__host {
    color: var(--c-accent);
    font-weight: 600;
    flex: none;
}

.url-row__path {
    color: var(--c-text-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.url-row__link:hover .url-row__path {
    color: var(--c-text-2);
}

.url-row__tag {
    flex: none;
    padding: 0 0.3rem;
    border: 1px solid var(--c-border);
    border-radius: var(--r-sm);
    color: var(--c-text-3);
    font-family: var(--font-sans);
    font-size: 0.625rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.copy-btn {
    flex: none;
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    border: none;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--c-text-3);
    cursor: pointer;
    opacity: 0;
    transition:
        opacity var(--dur) var(--ease),
        background-color var(--dur) var(--ease),
        color var(--dur) var(--ease);
}

.copy-btn svg {
    width: 0.875rem;
    height: 0.875rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.url-row:hover .copy-btn,
.copy-btn:focus-visible {
    opacity: 1;
}

.copy-btn:hover {
    background: var(--c-surface-3);
    color: var(--c-text);
}

@media (hover: none) {
    .copy-btn {
        opacity: 1;
    }
}

/* Skeleton placeholders while a platform is still searching */

.skeleton {
    height: 0.875rem;
    border-radius: var(--r-sm);
    background: linear-gradient(
        90deg,
        var(--c-surface-2) 0%,
        var(--c-surface-3) 40%,
        var(--c-surface-2) 80%
    );
    background-size: 200% 100%;
    animation: shimmer 1.4s ease-in-out infinite;
}

.skeleton-row {
    display: flex;
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-2);
}

.skeleton-row .skeleton:first-child {
    width: 30%;
}

.skeleton-row .skeleton:last-child {
    flex: 1;
}

@keyframes shimmer {
    0% {
        background-position: 100% 0;
    }
    100% {
        background-position: -100% 0;
    }
}

/* --------------------------------------------------------------------------
   10. Empty & error states
   -------------------------------------------------------------------------- */

.notice {
    align-self: center;
    width: 100%;
    max-width: var(--hero-max);
    display: flex;
    gap: var(--sp-3);
    padding: var(--sp-4);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    background: var(--c-surface);
    align-items: flex-start;
}

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

.notice__title {
    font-weight: 600;
}

.notice__body {
    color: var(--c-text-2);
    font-size: var(--text-sm);
    margin-top: var(--sp-1);
}

.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--sp-2);
    padding: var(--sp-12) var(--sp-6);
    border: 1px dashed var(--c-border-strong);
    border-radius: var(--r-lg);
    background: var(--c-surface);
}

.empty__icon {
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--r-md);
    background: var(--c-surface-2);
    color: var(--c-text-3);
}

.empty__icon svg {
    width: 1.25rem;
    height: 1.25rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.empty__title {
    font-size: var(--text-lg);
    font-weight: 600;
}

.empty__body {
    color: var(--c-text-3);
    max-width: 30rem;
}

/* --------------------------------------------------------------------------
   11. Toast
   -------------------------------------------------------------------------- */

.toast {
    position: fixed;
    left: 50%;
    bottom: var(--sp-8);
    transform: translateX(-50%);
    z-index: 50;
    padding: var(--sp-3) var(--sp-5);
    border-radius: var(--r-pill);
    background: var(--c-text);
    color: var(--c-canvas);
    font-size: var(--text-sm);
    font-weight: 500;
    box-shadow: var(--shadow-2);
    animation: toast-in 200ms var(--ease);
}

@keyframes toast-in {
    from {
        opacity: 0;
        transform: translate(-50%, 0.5rem);
    }
}

/* --------------------------------------------------------------------------
   12. Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 640px) {
    .page {
        padding: var(--sp-6) var(--sp-4) var(--sp-10);
        gap: var(--sp-6);
    }

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

    .intro__title {
        font-size: var(--text-2xl);
    }

    .intro__lede {
        font-size: var(--text-md);
    }

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

    .search__form {
        flex-direction: column;
        align-items: stretch;
    }

    /* Once the form stacks, flex-basis applies to the height instead of the
       width, so the field's 18rem basis would stretch it into a 288px-tall
       box with ~214px of dead space under the input. Size it to content. */
    .field {
        flex: 0 0 auto;
    }

    .search__btn {
        width: 100%;
    }

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

    .results {
        padding-inline: calc(var(--sp-4) + var(--hairline));
    }

    .results__head {
        align-items: stretch;
        flex-direction: column;
    }

    .results__actions .btn {
        flex: 1 1 auto;
    }

    .grid {
        grid-template-columns: 1fr;
    }
}

/* Below roughly 240px there is not enough room for a centred brand and a
   right-aligned toggle on one line, so the topbar drops to a plain
   two-item row and the wordmark truncates with an ellipsis. This is the
   width a 375px phone reaches at 200% browser zoom. */
@media (max-width: 240px) {
    .topbar__inner {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-2);
    }

    .brand {
        flex: 0 1 auto;
    }

    .icon-btn {
        flex: none;
    }

    /* A nowrap label cannot shrink below its own width, which pushed the
       action buttons past the content column. Let the label wrap instead. */
    .results__actions .btn {
        white-space: normal;
        padding-inline: 0.6rem;
    }
}

/* --------------------------------------------------------------------------
   13. Motion preferences
   -------------------------------------------------------------------------- */

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

    .spinner {
        border-top-color: var(--c-accent);
        animation: none;
        opacity: 0.8;
    }

    .pill--active .pill__dot {
        animation: none;
    }
}
