/* ============================================================
   components.css — global, reusable UI primitives.
   Promoted from the design-page sandbox. Every page in the app
   may use these classes. Tokens come from tokens.css.
   ============================================================ */

/* ============================================================
   Accessibility utilities
   ============================================================ */

.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;
}

/* ============================================================
   Buttons
   ============================================================ */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-8);
    padding: 10px 18px;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-family: inherit;
    font-size: var(--font-size-sm);
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    user-select: none;
    transition: background var(--motion-fast) var(--ease-standard),
                color      var(--motion-fast) var(--ease-standard),
                box-shadow var(--motion-fast) var(--ease-standard),
                transform  var(--motion-fast) var(--ease-standard);
    line-height: 1;
}

.btn:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

.btn:active:not(:disabled) {
    transform: translateY(1px);
}

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

.btn .icon { width: 16px; height: 16px; }

.btn-sm    { padding: 6px 12px;  font-size: var(--font-size-xs);   border-radius: var(--radius-sm); }
.btn-lg    { padding: 14px 24px; font-size: var(--font-size-base); border-radius: var(--radius-lg); }
.btn-icon  { padding: 10px; }
.btn-icon.btn-sm { padding: 6px; }
.btn-block { display: flex; width: 100%; }

.btn-primary {
    background: var(--zone-600, var(--admin-600));
    color: var(--text-inverse);
}
.btn-primary:hover:not(:disabled) {
    background: var(--zone-800, var(--admin-800));
    box-shadow: var(--elevation-1);
}

.btn-secondary {
    background: var(--surface-base);
    color: var(--text-primary);
    border-color: var(--border-base);
}
.btn-secondary:hover:not(:disabled) {
    background: var(--tint-hover);
    border-color: var(--border-strong);
}

.btn-outline {
    background: transparent;
    color: var(--zone-600, var(--text-primary));
    border-color: var(--zone-600, var(--border-strong));
}
.btn-outline:hover:not(:disabled) {
    background: var(--zone-600, var(--text-primary));
    color: var(--text-inverse);
}

.btn-ghost {
    background: transparent;
    color: var(--text-secondary);
}
.btn-ghost:hover:not(:disabled) {
    background: var(--tint-hover);
    color: var(--text-primary);
}

.btn-danger {
    background: var(--color-error);
    color: #fff;
}
.btn-danger:hover:not(:disabled) {
    background: color-mix(in srgb, var(--color-error) 75%, black);
    box-shadow: var(--elevation-1);
}

.btn-outline-danger {
    background: transparent;
    color: var(--color-error);
    border-color: var(--color-error);
}
.btn-outline-danger:hover:not(:disabled) {
    background: var(--color-error);
    color: #fff;
}

/* In dark mode, primary button text needs to stay dark because the
   background flips to a light shade (light btn on dark bg). */
[data-theme="dark"] .btn-primary {
    color: var(--surface-app);
}

/* ============================================================
   Form fields
   ============================================================ */

.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
    border: none;
    padding: 0;
    margin: 0;
}

.field-full { grid-column: 1 / -1; }

.field-label {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--text-primary);
}

.input {
    width: 100%;
    padding: 10px 12px;
    background: var(--surface-base);
    color: var(--text-primary);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-md);
    font-family: inherit;
    font-size: var(--font-size-base);
    transition: border-color var(--motion-fast) var(--ease-standard),
                box-shadow   var(--motion-fast) var(--ease-standard);
}

.input::placeholder { color: var(--text-muted); }

.input:hover { border-color: var(--border-strong); }

.input:focus {
    outline: none;
    border-color: var(--zone-600, var(--border-focus));
    box-shadow: var(--focus-ring);
}

.input.invalid {
    border-color: var(--color-error);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 25%, transparent);
}

textarea.input {
    resize: vertical;
    min-height: 88px;
    line-height: 1.5;
}

/* Baseline <select> styling — matches the .input look so every dropdown
   in the app renders correctly in both light and dark mode, even when the
   markup omits class="input". Width stays auto so inline selects don't
   stretch to fill their parent (the .input rule above wins for explicit
   class="input" selects and gives them the full-width form-field look). */
select {
    padding: 10px 12px;
    background: var(--surface-base);
    color: var(--text-primary);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-md);
    font-family: inherit;
    font-size: var(--font-size-base);
    transition: border-color var(--motion-fast) var(--ease-standard),
                box-shadow   var(--motion-fast) var(--ease-standard);
}

select:hover { border-color: var(--border-strong); }

select:focus {
    outline: none;
    border-color: var(--zone-600, var(--border-focus));
    box-shadow: var(--focus-ring);
}

/* Native color picker — let the colour swatch fill its box edge to edge.
   Browsers apply different default inner padding around the swatch which
   looks like an inset frame; zeroing it gives a clean rectangular chip. */
input[type="color"] {
    padding: 0;
}

/* ============================================================
   Dialog close button (×)
   Square, low-emphasis affordance for the top-right of any
   <dialog>. Hover lightens the background so it reads as
   interactive without competing with the dialog title.
   ============================================================ */
.btn-close-dialog {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--text-tertiary);
    font-family: inherit;
    font-size: var(--font-size-xl);
    line-height: 1;
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: background var(--motion-fast) var(--ease-standard),
                color      var(--motion-fast) var(--ease-standard);
}

.btn-close-dialog:hover {
    background: var(--tint-hover);
    color: var(--text-primary);
}

.btn-close-dialog:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

.field-error {
    font-size: var(--font-size-xs);
    color: var(--color-error);
}

/* Checkbox */
.check, .radio {
    /* Contain the visually-hidden <input> below. Without this the absolutely-positioned input
       escapes to the nearest positioned ancestor (often <body>) and renders far from its label;
       a real click focuses it there and the browser scrolls it into view, yanking the page. */
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--space-8);
    cursor: pointer;
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    user-select: none;
}

.check input, .radio input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
}

.check-box {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border: 1.5px solid var(--border-strong);
    background: var(--surface-base);
    border-radius: var(--radius-xs);
    transition: background var(--motion-fast) var(--ease-standard),
                border-color var(--motion-fast) var(--ease-standard);
}

.check input:checked + .check-box {
    background: var(--zone-600, var(--admin-600));
    border-color: var(--zone-600, var(--admin-600));
}

.check input:checked + .check-box::after {
    content: '';
    width: 10px;
    height: 6px;
    border-left: 2px solid var(--text-inverse);
    border-bottom: 2px solid var(--text-inverse);
    transform: rotate(-45deg) translate(1px, -1px);
}

.check input:focus-visible + .check-box,
.radio input:focus-visible + .radio-dot {
    box-shadow: var(--focus-ring);
}

/* Radio */
.radio-dot {
    display: inline-block;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 1.5px solid var(--border-strong);
    background: var(--surface-base);
    position: relative;
    transition: border-color var(--motion-fast) var(--ease-standard);
}

.radio input:checked + .radio-dot { border-color: var(--zone-600, var(--admin-600)); }

.radio input:checked + .radio-dot::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--zone-600, var(--admin-600));
    transform: translate(-50%, -50%);
}

/* Toggle */
.toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-12);
    cursor: pointer;
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    user-select: none;
}

.toggle input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
}

.toggle-track {
    position: relative;
    display: inline-block;
    width: 36px;
    height: 20px;
    background: var(--surface-sunken);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-pill);
    transition: background var(--motion-fast) var(--ease-standard),
                border-color var(--motion-fast) var(--ease-standard);
}

.toggle-thumb {
    position: absolute;
    top: 1px;
    left: 1px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--surface-base);
    box-shadow: var(--elevation-1);
    transition: transform var(--motion-base) var(--ease-emphasis);
}

.toggle.on .toggle-track {
    background: var(--zone-600, var(--admin-600));
    border-color: var(--zone-600, var(--admin-600));
}

.toggle.on .toggle-thumb { transform: translateX(16px); }

.toggle input:focus-visible + .toggle-track { box-shadow: var(--focus-ring); }

/* Dark mode: the sunken track blends into raised surfaces and the thumb's
   drop shadow disappears, leaving the knob reading as a lone circle. Give the
   track a stronger outline and the knob a light, clearly-raised face. */
[data-theme="dark"] .toggle-track { border-color: var(--border-strong); }
[data-theme="dark"] .toggle-thumb { background: var(--surface-inverse); }

/* ============================================================
   Cards
   ============================================================ */

.card {
    background: var(--surface-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-20);
    box-shadow: var(--elevation-1);
    display: flex;
    flex-direction: column;
    gap: var(--space-12);
    transition: box-shadow var(--motion-base) var(--ease-standard),
                transform  var(--motion-base) var(--ease-standard);
}

.card:hover {
    box-shadow: var(--elevation-2);
    transform: translateY(-2px);
}

.card-static:hover { box-shadow: var(--elevation-1); transform: none; }

.card-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-12);
}

.card-head h3 {
    margin: 0;
    font-size: var(--font-size-base);
    color: var(--text-primary);
}

.card-body {
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    line-height: 1.5;
}

.card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-12);
    margin-top: auto;
    padding-top: var(--space-8);
}

.card-price {
    font-size: var(--font-size-base);
    color: var(--zone-700, var(--text-primary));
}

/* ============================================================
   Dashboard / detail section — large content section card.
   Used by admin dashboard pages (club-setup, club-members,
   club-operations, club-financials, etc.) and detail pages
   (course-detail). Heavier padding than .card; comes with a
   bordered heading style. Use the *-heading classes for the
   primary section title and the *-subsection-heading for
   inline groupings inside.
   ============================================================ */

.dashboard-section,
.detail-section {
    background: var(--surface-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: var(--elevation-1);
    padding: var(--space-32);
    margin-bottom: var(--space-24);
}

.dashboard-section-heading,
.detail-section-heading {
    font-size: var(--font-size-lg);
    font-weight: 700;
    color: var(--text-primary);
    margin: 0 0 var(--space-24);
    padding-bottom: var(--space-16);
    border-bottom: 1px solid var(--border-subtle);
}

.dashboard-subsection-heading,
.detail-subsection-heading {
    font-size: var(--font-size-base);
    font-weight: 700;
    color: var(--text-primary);
    margin: var(--space-24) 0 var(--space-12);
}

@media (max-width: 767px) {
    .dashboard-section,
    .detail-section {
        padding: var(--space-20) var(--space-16);
    }
}

/* ============================================================
   Preview cards — small static teaser/snippet cards
   For example slices of data: a mini standings table or an upcoming
   event line. Lighter than .card
   (no hover lift, tighter padding) but more elevated by default.
   ============================================================ */

.preview-card {
    background: var(--surface-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-16);
    box-shadow: var(--elevation-2);
    font-size: var(--font-size-sm);
}

.preview-label {
    font-size: var(--font-size-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-tertiary);
    margin: 0 0 var(--space-8);
}

.preview-title {
    font-weight: 600;
    color: var(--text-primary);
    margin: 0 0 var(--space-4);
}

.preview-meta {
    color: var(--text-tertiary);
    font-size: var(--font-size-xs);
    margin: 0;
}

.preview-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-xs);
    color: var(--text-secondary);
}

.preview-table td { padding: 2px 4px; }

.preview-table td:last-child {
    text-align: right;
    font-weight: 600;
}

/* ============================================================
   Data table — full-width admin/listing tables.
   Pair with `<div class="data-table-wrap">` for horizontal scroll
   on narrow viewports. Pages can extend by adding their own class
   (e.g. <table class="data-table layout-table">) for column-
   specific overrides; bespoke .data-table-* classes don't need
   to redefine the base layout.
   ============================================================ */

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

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

.data-table thead { background: var(--surface-sunken); }

.data-table th {
    padding: var(--space-12) var(--space-16);
    text-align: left;
    font-size: var(--font-size-xs);
    font-weight: 700;
    color: var(--text-tertiary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-bottom: 1px solid var(--border-subtle);
    white-space: nowrap;
}

.data-table td {
    padding: var(--space-12) var(--space-16);
    color: var(--text-secondary);
    border-bottom: 1px solid var(--border-subtle);
    vertical-align: middle;
}

.data-table tbody tr:last-child td { border-bottom: none; }

.data-table tbody tr:hover { background: var(--tint-hover); }

/* ============================================================
   Badges & alerts
   ============================================================ */

.badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: var(--radius-pill);
    font-size: var(--font-size-xs);
    font-weight: 600;
    border: 1px solid transparent;
}

.badge-success { background: var(--color-success-bg); color: var(--color-success-fg); border-color: color-mix(in srgb, var(--color-success-border) 30%, transparent); }
.badge-warning { background: var(--color-warning-bg); color: var(--color-warning-fg); border-color: color-mix(in srgb, var(--color-warning-border) 30%, transparent); }
.badge-error   { background: var(--color-error-bg);   color: var(--color-error);      border-color: color-mix(in srgb, var(--color-error) 30%, transparent); }
.badge-info    { background: var(--color-info-bg);    color: var(--color-info-fg);    border-color: color-mix(in srgb, var(--color-info-border) 30%, transparent); }
.badge-neutral { background: var(--surface-sunken);   color: var(--text-secondary);   border-color: var(--border-base); }

/* Beginner-friendly badge — shared by the club detail page and the clubs
   directory card so both surfaces read identically. */
.beginner-badge-tag {
    display: inline-block;
    padding: 4px 12px;
    background: var(--color-success);
    color: var(--text-inverse);
    font-size: var(--font-size-xs);
    font-weight: 700;
    border-radius: var(--radius-pill);
    letter-spacing: 0.02em;
}

/* Role badge — neutral base for club role chips. Pages add their own
   `.role-admin` / `.role-organizer` / `.role-member` modifiers since
   the visual treatment differs by surface (admin pages use a flat
   pill; the public club page uses a heavier "admin only" badge). */
.role-badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: var(--radius-pill);
    font-size: var(--font-size-xs);
    font-weight: 600;
    text-transform: capitalize;
}

.alert {
    display: flex;
    align-items: flex-start;
    gap: var(--space-12);
    padding: var(--space-16);
    border-radius: var(--radius-md);
    border: 1px solid;
    border-left-width: 4px;
}

.alert .icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    margin-top: 2px;
}

.alert strong { display: block; font-size: var(--font-size-sm); margin-bottom: 2px; }
.alert p      { margin: 0; font-size: var(--font-size-sm); line-height: 1.5; }

.alert-success { background: var(--color-success-bg); color: var(--color-success-fg); border-color: var(--color-success-border); }
.alert-info    { background: var(--color-info-bg);    color: var(--color-info-fg);    border-color: var(--color-info-border); }
.alert-warning { background: var(--color-warning-bg); color: var(--color-warning-fg); border-color: var(--color-warning-border); }
.alert-error   { background: var(--color-error-bg);   color: var(--color-error);      border-color: var(--color-error); }

/* ============================================================
   Tabs
   ============================================================ */

.tab-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 0;
    border-bottom: 1px solid var(--border-base);
    margin-bottom: var(--space-20);
}

.tab {
    background: transparent;
    border: none;
    padding: var(--space-12) var(--space-16);
    font-family: inherit;
    font-size: var(--font-size-sm);
    font-weight: 500;
    color: var(--text-tertiary);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color var(--motion-fast) var(--ease-standard),
                border-color var(--motion-fast) var(--ease-standard);
}

.tab:hover { color: var(--text-primary); }

.tab.active {
    color: var(--text-primary);
    border-bottom-color: var(--zone-600, var(--admin-600));
}

.tab:focus-visible {
    outline: none;
    border-radius: var(--radius-xs);
    box-shadow: var(--focus-ring);
}

.tab-panel {
    padding: var(--space-16);
    background: var(--surface-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}

/* ============================================================
   Segmented control
   ============================================================ */

.segmented {
    display: inline-flex;
    padding: 3px;
    background: var(--surface-sunken);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-pill);
    gap: 2px;
}

.segment {
    display: inline-flex;
    align-items: center;
    gap: var(--space-8);
    padding: 6px 14px;
    border: none;
    background: transparent;
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    font-weight: 500;
    cursor: pointer;
    border-radius: var(--radius-pill);
    transition: background var(--motion-fast) var(--ease-standard),
                color      var(--motion-fast) var(--ease-standard),
                box-shadow var(--motion-fast) var(--ease-standard);
}

.segment:hover { color: var(--text-primary); }

.segment.active {
    background: var(--surface-raised);
    color: var(--text-primary);
    box-shadow: var(--elevation-1), inset 0 0 0 1px var(--border-base);
}

.segment:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

.segment .icon { width: 16px; height: 16px; }

/* ============================================================
   Sub-nav pill bar — admin / sectioned page sub-navigation.
   Wraps anchor links that switch between sub-pages of an admin
   surface (club-members, club-operations, club-league-admin, …).
   Active link fills with the zone primary; hover gives a tinted
   surface. Each link is an <a is="anchor-state" class="subnav-pill-link">
   inside a <nav class="subnav-pill-bar">.
   ============================================================ */

.subnav-pill-bar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-8);
    margin-bottom: var(--space-24);
    padding: var(--space-8);
    background: var(--surface-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: var(--elevation-1);
}

.subnav-pill-link {
    padding: var(--space-8) var(--space-16);
    border-radius: var(--radius-pill);
    color: var(--zone-700, var(--admin-700));
    font-size: var(--font-size-sm);
    font-weight: 600;
    text-decoration: none;
    transition: background var(--motion-fast) var(--ease-standard),
                color      var(--motion-fast) var(--ease-standard);
}

.subnav-pill-link:hover {
    background: var(--surface-sunken);
    color: var(--text-primary);
}

.subnav-pill-link.active {
    background: var(--zone-600, var(--admin-600));
    color: var(--text-inverse);
}

.subnav-pill-link:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

/* ============================================================
   Filter bar — directory page filter row
   Used by event / course / club directories. Children are typically
   <label class="field filter-group"> wrapping an <input class="input">
   or <select class="input">. Controls share spacing, colour, and the
   raised surface so the bar reads as a single component.
   ============================================================ */

.filter-bar {
    display: flex;
    align-items: center;
    gap: var(--space-16);
    flex-wrap: wrap;
    margin-bottom: var(--space-32);
    padding: var(--space-16) var(--space-20);
    background: var(--surface-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: var(--elevation-1);
}

.filter-group {
    flex: 0 1 auto;
    min-width: 180px;
}

.filter-group .field-label {
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-tertiary);
}

.filter-search-input { width: 240px; }

.filter-within-row {
    display: flex;
    gap: var(--space-8);
    align-items: stretch;
}

.filter-within-row .input {
    flex: 1;
    min-width: 0;
}

@media (max-width: 767px) {
    .filter-bar { flex-direction: column; }

    .filter-search-input,
    .filter-group { width: 100%; }
}

/* ============================================================
   Directory page — shared layout for /club-hub, /courses, …
   Pairs with .filter-bar above. The page wraps a toolbar +
   filter-bar + grid + (loading / empty-state) flow with the
   `.directory-*` classes here; per-page CSS only adds rules
   for entity-specific embellishments (cover photos, ratings, …).
   ============================================================ */

.directory-toolbar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-12);
    flex-wrap: wrap;
    margin-bottom: var(--space-16);
}

.directory-loading {
    color: var(--text-tertiary);
    font-size: var(--font-size-sm);
    margin-bottom: var(--space-16);
}

.directory-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--space-20);
}

.directory-card {
    position: relative;
    background: var(--surface-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    border-top: 4px solid var(--zone-400);
    overflow: hidden;
    box-shadow: var(--elevation-1);
    display: flex;
    flex-direction: row;
    transition: box-shadow var(--motion-base) var(--ease-standard),
                transform  var(--motion-base) var(--ease-standard);
}

.directory-card:hover {
    box-shadow: var(--elevation-2);
    transform: translateY(-2px);
}

/* Favorite star, overlaid top-right. Only rendered for signed-in visitors. */
.directory-card-favorite {
    position: absolute;
    top: var(--space-4);
    right: var(--space-4);
    z-index: 1;
}

/* Left-side image strip — top to bottom, fixed width. Falls back to a
   tinted placeholder block when no image is supplied. */
.directory-card-image {
    flex: 0 0 120px;
    background: var(--zone-100);
    overflow: hidden;
}

.directory-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.directory-card-body {
    flex: 1;
    min-width: 0;
    padding: var(--space-24);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.directory-card-name {
    font-size: var(--font-size-lg);
    font-weight: 700;
    color: var(--text-primary);
    margin: 0;
}

.directory-card-location {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    margin: 0;
}

/* The card body is a flex column, so a badge would stretch to the full card
   width — keep it sized to its text. */
.directory-card-body .beginner-badge-tag {
    align-self: flex-start;
}

.directory-card-meta {
    font-size: var(--font-size-sm);
    color: var(--text-tertiary);
    margin: 0 0 var(--space-12);
}

.directory-card-meta-link {
    color: var(--text-link);
    text-decoration: none;
    font-weight: 600;
}

.directory-card-meta-link:hover { color: var(--text-link-hover); text-decoration: underline; }

.directory-card-meta-link:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
    border-radius: var(--radius-xs);
}

/* Optional sub-list inside a directory card — e.g. courses under a club. */
.directory-card-list {
    list-style: none;
    margin: 0 0 var(--space-12);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.directory-card-list-link {
    font-size: var(--font-size-sm);
    color: var(--text-link);
    text-decoration: none;
}

.directory-card-list-link:hover { color: var(--text-link-hover); text-decoration: underline; }

.directory-card-list-link:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
    border-radius: var(--radius-xs);
}

.directory-card-link {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--text-link);
    text-decoration: none;
    margin-top: auto;
    transition: color var(--motion-fast) var(--ease-standard);
}

.directory-card-link:hover {
    color: var(--text-link-hover);
    text-decoration: underline;
}

.directory-card-link:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
    border-radius: var(--radius-xs);
}

/* Empty state — shared by directory pages and any list/grid that may
   render zero results (`.empty-state` is the canonical name; the
   `.directory-empty-*` aliases are kept for the existing directory
   markup but new code should use the un-prefixed forms). */
.empty-state,
.directory-empty-state {
    text-align: center;
    max-width: 480px;
    margin: var(--space-64) auto;
    padding: var(--space-48) var(--space-32);
    background: var(--surface-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: var(--elevation-1);
}

.empty-state-heading,
.empty-heading,
.directory-empty-heading {
    font-size: var(--font-size-xl);
    font-weight: 700;
    color: var(--text-primary);
    margin: 0 0 var(--space-12);
}

.empty-state-body,
.empty-body,
.directory-empty-body {
    font-size: var(--font-size-base);
    color: var(--text-secondary);
    line-height: 1.6;
    margin: 0 0 var(--space-24);
}

.empty-state-actions,
.empty-actions,
.directory-empty-actions {
    display: flex;
    justify-content: center;
    gap: var(--space-12);
    flex-wrap: wrap;
}

/* ============================================================
   Chip — small status / metadata pill (non-interactive)
   ============================================================ */

.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-8);
    padding: 6px 12px;
    background: var(--surface-base);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-pill);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.chip .icon {
    width: 14px;
    height: 14px;
    color: var(--zone-600, var(--text-tertiary));
}

/* ============================================================
   Icon utility — used everywhere
   ============================================================ */

.icon {
    display: inline-block;
    width: 18px;
    height: 18px;
    vertical-align: -2px;
    color: currentColor;
    flex-shrink: 0;
}

/* ============================================================
   Reduced motion
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
    .btn, .input, .check-box, .radio-dot, .toggle-track, .toggle-thumb,
    .card, .tab, .segment {
        transition-duration: 1ms !important;
    }
}
