/*
 * Every CSS rule that targets an Ark-owned name — a class starting `ark-`, or a
 * `data-ark-*` attribute — lives here, and both catalogs link it.
 *
 * Why this file exists rather than Blazor scoped CSS: scoped `.razor.css` compiles
 * to `[b-hash]` attribute selectors that only match markup Blazor rendered. The React
 * catalog emits the same class names, so under scoping it emitted class names with no
 * rules behind them and rendered unstyled.
 *
 * What does NOT belong here: rules targeting MudBlazor internals (`.mud-*`), which stay
 * in the owning `.razor.css`, and rules targeting PrimeReact internals (`.p-*`), which
 * live in the React workspace's `theme/ark-prime-overrides.css`.
 *
 * Load order matters. Both catalogs link this after `ark-tokens.css` (so the tokens it
 * references are defined) and after their component library's own stylesheet (so these
 * rules win the cascade). Unscoping lowered specificity — `.ark-specimen[b-hash]` became
 * `.ark-specimen` — so source order is now what keeps MudBlazor from overriding Ark.
 *
 * ScopedCssBoundaryTests enforces both halves of that split.
 */

/* ---- ArkSpecimen ---- */

.ark-specimen {
    display: grid;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--card);
    box-shadow: var(--shadow-sm);
}

.ark-specimen__head {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    padding: 18px 20px;
    border-bottom: 1px solid var(--border);
}

.ark-specimen__number {
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    flex: 0 0 42px;
    border-radius: 13px;
    /* Fixed brand stops, not --primary-color/--tertiary-color: those lighten in
       dark mode and the white numeral drops to 2.7:1 against them. A brand tile
       holds its colour across themes; only the shadow below follows the theme. */
    background: linear-gradient(135deg, var(--brand-primary), var(--brand-tertiary));
    box-shadow: var(--shadow-md);
    color: var(--overlay-foreground);
    font-size: 0.9rem;
    font-weight: 800;
}

.ark-specimen__title {
    margin: 0;
    color: var(--text-header);
    font-size: 1.35rem;
    font-weight: 800;
    letter-spacing: -0.025em;
}

.ark-specimen__body {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(14rem, 1fr);
    align-items: start;
}

.ark-specimen__live {
    display: grid;
    gap: var(--spacing-lg);
    align-content: start;
    min-width: 0;
    padding: var(--spacing-lg);
}

.ark-specimen__state {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-md);
    min-width: 0;
    height: 100%;
    padding: var(--spacing-lg);
    overflow-x: auto;
    border-left: 1px solid var(--border);
    background: var(--muted);
    color: var(--text-secondary);
}

@media (max-width: 900px) {
    .ark-specimen__body {
        grid-template-columns: 1fr;
    }

    .ark-specimen__state {
        border-top: 1px solid var(--border);
        border-left: 0;
    }
}

/* Full-width demos (PDF viewer) put the state column below the live area
   instead of beside it, so the content gets the whole specimen width. */
.ark-specimen__body--full-width {
    grid-template-columns: minmax(0, 1fr);
}

.ark-specimen__body--full-width .ark-specimen__state {
    border-top: 1px solid var(--border);
    border-left: 0;
}

/* ---- ArkArcGauge ---- */

[data-ark-arc-gauge] {
    display: block;
    max-width: 12rem;
    color: var(--text);
}

[data-ark-arc-gauge] svg {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}

/* The track has to be a distinct surface from the fill, otherwise the arc reads
   as one solid band and the percentage is invisible. --grid-header-line is the
   only neutral that stays visible against both themes' card surfaces. */
.ark-arc-gauge__track {
    stroke: var(--grid-header-line);
}

/* --chart-1 is the brand teal that lightens to the brand-400 stop in dark mode,
   so one declaration reads on both canvases. This used to be --primary-color
   plus a pair of per-theme overrides that swapped the hue to the lime because
   the fixed teal went muddy on graphite. */
.ark-arc-gauge__fill {
    stroke: var(--chart-1);
    stroke-linecap: round;
    transition: stroke-dasharray var(--motion-fast) ease;
}

.ark-arc-gauge__value {
    font-family: var(--font-family-heading);
    font-size: 14px;
    font-weight: var(--font-weight-bold);
}

/* ---- ArkChart ---- */

.ark-chart {
    min-height: 24rem;
    padding: clamp(16px, 3vw, 28px);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--muted);
}

.ark-chart svg {
    display: block;
    width: 100%;
    min-height: 20rem;
    overflow: visible;
}

.ark-chart__grid {
    stroke: var(--chart-grid);
    stroke-width: 0.35;
    vector-effect: non-scaling-stroke;
}

.ark-chart__area {
    fill: var(--primary-soft);
}

.ark-chart__line {
    fill: none;
    stroke: var(--chart-1);
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-width: 1.35;
    vector-effect: non-scaling-stroke;
}

.ark-chart__point {
    fill: var(--chart-3);
    stroke: var(--muted);
    stroke-width: 0.8;
    vector-effect: non-scaling-stroke;
}

.ark-chart__labels {
    position: relative;
    min-height: 1.5rem;
}

.ark-chart__label {
    position: absolute;
    transform: translateX(-50%);
    color: var(--text-secondary);
    font-size: 0.75rem;
    font-weight: 700;
    text-align: center;
}

@media (max-width: 600px) {
    .ark-chart {
        min-height: 18rem;
        padding: 12px;
    }

    .ark-chart svg {
        min-height: 16rem;
    }
}

/* ---- ArkGantt ---- */

[data-ark-gantt] td:last-child {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    min-width: 14rem;
}

.ark-gantt__track {
    flex: 1;
    height: 10px;
    overflow: hidden;
    border-radius: 999px;
    background: var(--surface-bg-2);
}

.ark-gantt__bar {
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
}

.ark-gantt__value {
    min-width: 3rem;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/* ---- ArkListView ---- */

[data-ark-list-view] ul {
    display: grid;
    gap: var(--spacing-sm);
    margin: 0;
    padding: 0;
    list-style: none;
}

[data-ark-list-view] li {
    padding: var(--spacing-md);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--muted);
    transition: border-color var(--motion-fast), background-color var(--motion-fast);
}

[data-ark-list-view] li:hover {
    border-color: var(--primary-color);
    background: var(--hover-surface);
}

/* ---- ArkPivotGrid ---- */

[data-ark-pivot-grid] td:first-child {
    color: var(--text-header);
    font-weight: var(--font-weight-bold);
    text-align: left;
}

[data-ark-pivot-grid] td:not(:first-child) {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

[data-ark-pivot-grid] td:last-child {
    border-left: 1px solid var(--border);
    color: var(--text-header);
    font-weight: var(--font-weight-bold);
}

/* ---- ArkScheduler ---- */

[data-ark-scheduler] td {
    display: flex;
    align-items: baseline;
    gap: var(--spacing-sm);
}

.ark-scheduler__date {
    color: var(--text-header);
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-bold);
}

.ark-scheduler__time {
    padding: 2px var(--spacing-sm);
    border-radius: var(--radius-sm);
    background: var(--selection);
    color: var(--text-secondary);
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
}

/* ---- ArkSpreadsheet ---- */

[data-ark-spreadsheet] {
    display: block;
    max-width: 100%;
}

/* The spreadsheet is the tallest table in the catalog; everything else is
   happy with the shared default. Override the variable rather than
   redeclaring max-height, so the sticky header keeps working. */
[data-ark-spreadsheet] .ark-table-scroll {
    --ark-table-max-height: 32rem;
}

/* ---- ArkTileLayout ---- */

[data-ark-tile-layout] {
    align-items: stretch;
}

@media (max-width: 900px) {
    /* ArkTileLayout writes grid-template-columns as an inline style, which
       otherwise wins. This is the only !important in the codebase. */
    [data-ark-tile-layout] {
        grid-template-columns: minmax(0, 1fr) !important;
    }
}

/* ---- ArkTreeMap ---- */

[data-ark-tree-map] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    min-height: 16rem;
}

/*
 * flex-basis must be 0, not a width. flex-grow only distributes space left
 * over after every basis is satisfied, so a basis of 8rem consumed most of
 * each tile and squeezed a 10% spread in value into a 3% spread in width —
 * proportional in arithmetic, invisible on screen. At 0 the growth factors
 * govern the whole row, so tile width tracks value directly. min-width keeps
 * a small category readable rather than collapsing to its padding.
 */
[data-ark-tree-map-item] {
    display: flex;
    flex-direction: column;
    flex-basis: 0;
    flex-shrink: 1;
    justify-content: space-between;
    min-width: 7rem;
    min-height: 7rem;
    padding: var(--spacing-md);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    /* Soft forms of two chart hues rather than fixed brand rgba: --chart-1 and
       --chart-3 lighten in dark mode, so the tile keeps the same weight against
       graphite instead of sinking into it. */
    background: linear-gradient(155deg,
        oklch(from var(--chart-1) l c h / 0.22),
        oklch(from var(--chart-3) l c h / 0.14));
    color: var(--text-header);
}

[data-ark-tree-map-item] span {
    color: var(--text-secondary);
    font-size: 0.75rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

[data-ark-tree-map-item] strong {
    font-size: 1.1rem;
    font-variant-numeric: tabular-nums;
}

/* ---- ArkColorPalette ---- */

.ark-color-palette {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    padding: var(--spacing-sm);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background-color: var(--surface-bg);
    width: fit-content;
}

.ark-color-palette__swatch {
    display: block;
    padding: 0;
    border: 2px solid var(--border-color-secondary);
    border-radius: var(--radius-sm);
    background: none;
    cursor: pointer;
    line-height: 0;
}

.ark-color-palette__swatch[aria-checked="true"] {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 2px var(--primary-color);
}

.ark-color-palette__swatch:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

.ark-color-palette__swatch:disabled {
    cursor: not-allowed;
    opacity: 0.5;
}

.ark-color-palette__chip {
    display: block;
    width: 24px;
    height: 24px;
    border-radius: var(--radius-sm);
    background-color: var(--ark-swatch);
}

/* ---- ArkUpload ---- */

.ark-upload {
    display: grid;
    gap: var(--spacing-md);
    justify-items: start;
    padding: var(--spacing-md);
    border: 1px dashed var(--border-color-secondary);
    border-radius: var(--radius-md);
    background-color: var(--surface-subtle);
}

.ark-upload__list {
    list-style: none;
    display: grid;
    gap: var(--spacing-sm);
    width: 100%;
    margin: 0;
    padding: 0;
}

.ark-upload__item {
    display: grid;
    gap: var(--spacing-xs);
    padding: var(--spacing-sm);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background-color: var(--surface-bg);
}

.ark-upload__row {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
}

.ark-upload__name {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
    color: var(--text);
}

.ark-upload__size,
.ark-upload__status {
    flex: 0 0 auto;
    font-family: var(--font-family-mono);
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* ---- ArkQrCode ---- */

/*
 * A QR code is a scannable artefact, not a themed graphic: scanners need dark
 * modules on a light ground. The card stays white in both themes and the
 * modules are pinned to black, with a quiet zone so the code stays readable
 * against the dark workspace. The two literal colours below are deliberate
 * and are the only ones permitted here — they are not theme colours, they
 * are the black and white a scanner requires.
 *
 * The `rect` rule targets the Blazor ArkQrCode.razor placeholder, which draws
 * one <rect> per module. The React catalog uses qrcode.react's QRCodeSVG,
 * which instead renders two <path> elements (background, modules) with
 * fill="#FFFFFF"/"#000000" set inline by the library — so `rect` matches
 * nothing there, but no CSS hook is needed on that side either: the colours
 * are already correct without it.
 */
[data-ark-qr-code] {
    display: inline-block;
    padding: var(--spacing-md);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: #ffffff;
    line-height: 0;
}

[data-ark-qr-code] svg {
    display: block;
}

[data-ark-qr-code] rect {
    fill: #000000;
}

/* ---- ArkSplitter ---- */

.ark-splitter {
    --ark-splitter-first: 50%;

    display: grid;
    min-height: 22rem;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-glass);
}

.ark-splitter-horizontal {
    grid-template-columns: var(--ark-splitter-first) auto 1fr;
}

.ark-splitter-vertical {
    grid-template-rows: var(--ark-splitter-first) auto 1fr;
}

.ark-splitter-pane {
    min-width: 0;
    min-height: 0;
    overflow: auto;
    padding: var(--spacing-md);
}

.ark-splitter-divider {
    position: relative;
    background: var(--border);
    touch-action: none;
}

.ark-splitter-horizontal > .ark-splitter-divider {
    width: 5px;
    cursor: col-resize;
}

.ark-splitter-vertical > .ark-splitter-divider {
    height: 5px;
    cursor: row-resize;
}

.ark-splitter-divider:hover,
.ark-splitter-divider:focus-visible,
[data-ark-splitter-dragging] > .ark-splitter-divider {
    background: var(--primary-color);
}

/* Grip marks: signal that the divider is draggable. */
.ark-splitter-divider::after {
    content: "";
    position: absolute;
    inset: 50% auto auto 50%;
    width: 3px;
    height: 28px;
    transform: translate(-50%, -50%);
    border-radius: 999px;
    background: var(--surface-bg);
}

.ark-splitter-vertical > .ark-splitter-divider::after {
    width: 28px;
    height: 3px;
}

/* ---- ArkPdfViewer ---- */

[data-ark-pdf-viewer] {
    display: block;
    width: 100%;
}

/* Overrides the iframe's width/height attributes so the viewer scales with
   its container instead of sitting at a fixed pixel size. */
[data-ark-pdf-viewer] iframe {
    display: block;
    width: 100%;
    min-height: 70vh;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-subtle);
}

/* ---- ArkGrid ---- */

/* MudDataGrid sizes to its content, so the grid region scrolls horizontally
   rather than overflowing across whatever sits beside it. AG Grid on the React
   side is given an explicit height by the component, but the same overflow
   guard applies to its pager row. */
.ark-grid {
    display: grid;
    gap: var(--spacing-sm);
    min-width: 0;
    max-width: 100%;
    overflow-x: auto;
}

.ark-grid__loading {
    border: 1px solid var(--border);
    border-bottom: none;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
}

.ark-grid__empty {
    padding: var(--spacing-lg);
    text-align: center;
    font-family: var(--font-family-base);
    color: var(--text-muted);
}

.ark-grid__error {
    display: grid;
    gap: var(--spacing-sm);
    justify-items: start;
    padding: var(--spacing-md);
    background-color: var(--danger-bg);
    border: 1px solid var(--danger-border);
    border-radius: var(--radius-md);
}

.ark-grid__error-text {
    margin: 0;
    font-family: var(--font-family-base);
    font-weight: var(--font-weight-bold);
    color: var(--danger-text);
}

/* ---- ArkForm ---- */

.ark-form {
    display: grid;
    gap: var(--spacing-md);
}

/* Fields reflow by available width rather than a fixed column count, so the
   same form works in the specimen rail and full width. */
.ark-form__fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(var(--ark-form-field-min, 16rem), 1fr));
    gap: var(--spacing-md);
    align-items: start;
}

.ark-form__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
}

.ark-form__summary {
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--danger-border);
    border-radius: var(--radius-md);
    background-color: var(--danger-bg);
    color: var(--danger-text);
}

.ark-form__summary:empty,
.ark-form__summary:has(ul:empty) {
    display: none;
}

/* Blazor needs a `::deep` copy of this rule, kept in ArkForm.razor.css, because
   MudBlazor renders the list. React renders its own, so the plain form applies. */
.ark-form__summary ul {
    margin: 0;
    padding-left: var(--spacing-md);
}

/* ---- ArkColorPicker ---- */

.ark-color-picker {
    display: flex;
    align-items: flex-start;
    gap: var(--spacing-xs);
}

/* ---- ArkDateTimePicker ---- */

.ark-date-time-picker {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    align-items: flex-start;
}

/* The two picker controls share the row. On the Blazor side these are MudBlazor
   components reached via `> ::deep *`, kept in the scoped file; React renders
   PrimeReact Calendars as direct children, which this rule matches. */
.ark-date-time-picker > * {
    flex: 1 1 12rem;
    min-width: 0;
}

/* The helper describes both pickers, so it takes a whole flex line beneath
   them instead of competing with them for width. */
.ark-date-time-picker .ark-date-time-picker__helper {
    flex: 1 1 100%;
    margin-top: var(--spacing-xs);
    color: var(--text-muted);
}

/* ---- ArkMultiSelect ---- */

.ark-multi-select {
    display: grid;
    gap: var(--spacing-sm);
    align-content: start;
    padding: var(--spacing-sm);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background-color: var(--surface-bg);
}

/* These three are duplicated with `::deep` in ArkMultiSelect.razor.css for Blazor,
   where MudBlazor owns the elements. React renders them directly. Change together. */
.ark-multi-select .ark-multi-select__label {
    color: var(--text-header);
    font-weight: var(--font-weight-bold);
}

/* The chip set and the empty-state caption occupy the same slot. Reserving a
   shared minimum height keeps sibling fields aligned all the way down to the
   search input, whether or not either has a selection. */
.ark-multi-select .ark-multi-select__chips,
.ark-multi-select .ark-multi-select__empty {
    display: flex;
    align-items: center;
    min-height: 2rem;
    margin: 0;
}

.ark-multi-select .ark-multi-select__empty {
    color: var(--text-muted);
}

/* ---- Demo page layout ---- */

/* stretch, not flex-start: sibling fields in a row are the same kind of thing,
   so they should share a height even when their internal content differs. */
.specimen-row {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-md);
}

.grid-demo__controls {
    display: grid;
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-md);
}

.grid-demo__buttons {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
}

.grid-demo__note {
    margin: 0 0 var(--spacing-sm);
    padding: var(--spacing-xs) var(--spacing-sm);
    border: 1px solid var(--info-border);
    border-radius: var(--radius-sm);
    background-color: var(--info-bg);
    color: var(--info-text);
    font-family: var(--font-family-mono);
    font-size: 0.75rem;
    letter-spacing: 0.04em;
}

/* ---- Data demo shell ---- */

.data-demo__error {
    display: grid;
    gap: var(--spacing-sm);
    justify-items: start;
    padding: var(--spacing-md);
    border: 1px solid var(--danger-border);
    border-radius: var(--radius-md);
    background: var(--danger-bg);
    color: var(--danger-text);
}

.data-demo__pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-sm);
}

.data-demo__pager-total {
    color: var(--text-secondary);
    font-family: var(--font-family-mono);
    font-size: 0.75rem;
}

/* ---- JsonStatePanel ---- */

.json-state {
    display: grid;
    gap: var(--spacing-sm);
}

.json-state__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-sm);
}

.json-state__title {
    margin: 0;
    color: var(--tertiary-color);
    font-family: var(--font-family-base);
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0.01em;
}

.json-state__toggle {
    flex: 0 0 auto;
    padding: 2px 9px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-glass-strong);
    color: var(--text-secondary);
    font-family: var(--font-family-base);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    transition-duration: var(--motion-fast);
    transition-property: color, border-color, background-color;
}

.json-state__toggle:hover,
.json-state__toggle:focus-visible {
    border-color: var(--primary-color);
    color: var(--text-header);
}

.json-state__empty {
    margin: 0;
    font-family: var(--font-family-mono);
    font-size: 0.75rem;
    color: var(--text-muted);
}

.json-state__pre {
    margin: 0;
    max-height: 22rem;
    overflow: auto;
    padding: var(--spacing-md);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--muted);
    color: var(--text);
    font-family: var(--font-family-mono);
    font-size: 0.75rem;
    line-height: 1.55;
    white-space: pre;
}

/* ===========================================================================
   Catalog landing — the per-library overview at /blazor and /react.
   ---------------------------------------------------------------------------
   These rules used to live in Pages/Home.razor.css, on the documented
   assumption that the landing was Blazor-only chrome. It is not any more: the
   React catalog renders the same markup at /react, so the rules moved here to
   the sheet both catalogs link. That is what keeps the two landings identical
   instead of two hand-matched copies that drift.

   Surface treatment follows the ARKSOFT platform's cards rather than the
   glass-over-glow the Blazor page used to carry: a solid --card tier, a
   hairline --border and one elevation step. Translucency is for chrome that
   floats over content (the app bar, the nav rail), not for a card the reader
   has to get text out of.
   ========================================================================= */

.ark-home {
    display: grid;
    gap: var(--spacing-lg);
}

.ark-home__hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--spacing-lg);
}

.ark-home__eyebrow {
    color: var(--primary-color);
    font-size: 0.75rem;
    font-weight: var(--font-weight-bold);
    letter-spacing: 0.13em;
    text-transform: uppercase;
}

.ark-home h1 {
    max-width: 46rem;
    /* Restrained against the old clamp(2.6rem, 7vw, 5.8rem) at -0.07em: the
       platform's display scale tops out far lower and tracks at
       --tracking-display, so the hero now reads as the same typeface family
       rather than a poster. */
    margin: var(--spacing-sm) 0 0;
    font-size: clamp(2.25rem, 5.5vw, 3.75rem);
    line-height: 1.04;
    letter-spacing: var(--tracking-display);
}

/* The hero heading receives focus on navigation, not from the user tabbing to
   it — nobody keyboard-navigates to an <h1>. Painting the global focus ring on
   it just flashes a box around the title on every page load, so it is
   suppressed here. Interactive elements keep their ring. */
.ark-home h1:focus {
    outline: none;
}

.ark-home h1 em {
    /* --tertiary-color carries a lighter stop in dark mode; the brand purple
       itself is only ~2.1:1 on graphite. */
    color: var(--tertiary-color);
    font-style: normal;
}

.ark-home__hero p {
    max-width: 42rem;
    margin: var(--spacing-md) 0 0;
    color: var(--text-secondary);
    font-size: 1rem;
    line-height: 1.6;
}

/* The oversized numeral behind the hero. Decorative and aria-hidden — the
   accessible count is the adjacent screen-reader span. --primary-soft is a
   theme-flipping wash (10% of the brand teal in light, 18% of the lighter
   dark-mode stop), which is what stops it vanishing on graphite the way the
   old fixed rgba(42, 101, 114, 0.12) did. */
.ark-home__count {
    color: var(--primary-soft);
    font-family: var(--font-display);
    font-size: clamp(4.5rem, 11vw, 8rem);
    font-weight: var(--font-weight-bold);
    line-height: 0.8;
    letter-spacing: var(--tracking-display);
}

.ark-home__sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.ark-home__categories {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: var(--spacing-md);
}

.ark-home__category {
    overflow: hidden;
    padding: var(--spacing-lg);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--card);
    box-shadow: var(--shadow-sm);
}

.ark-home__category header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--spacing-sm);
    padding-bottom: var(--spacing-sm);
    border-bottom: 1px solid var(--border);
}

.ark-home__category h2 {
    margin: 0;
    font-size: 1.0625rem;
    letter-spacing: var(--tracking-tight);
}

/* The per-category count. Teal, not the brand purple this used to wear: at
   12px the purple missed AA on the dark canvas by a wide margin, and the
   eyebrow above already establishes teal as the catalog's meta colour. */
.ark-home__category header span {
    color: var(--primary-color);
    font-size: 0.75rem;
    font-weight: var(--font-weight-bold);
    white-space: nowrap;
}

.ark-home__category ul {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: 2px;
    margin: var(--spacing-md) 0 0;
    padding: 0;
    list-style: none;
}

.ark-home__category a {
    display: block;
    padding: var(--spacing-xs) var(--spacing-sm);
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    text-decoration: none;
    transition: background-color var(--duration-fast) var(--ease-out-cubic),
                color var(--duration-fast) var(--ease-out-cubic);
}

.ark-home__category a:hover,
.ark-home__category a:focus-visible {
    background: var(--accent);
    color: var(--text-header);
}

@media (prefers-reduced-motion: reduce) {
    .ark-home__category a {
        transition: none;
    }
}

@media (max-width: 760px) {
    .ark-home__hero {
        grid-template-columns: 1fr;
    }

    .ark-home__count {
        display: none;
    }
}
