/* ==========================================================================
   components.css - Shared components of the design system.
   Loaded by every page (app and public). Tokens (--ds-*) live in base.css.

    1. Buttons                    2. Links
    3. Badges, tones, avatars     4. Cards (feed, urgent, restricted)
    5. Dashboard blocks: section card, list rows, date chip
    6. Empty states, skeletons    7. Choice cards
    8. Alerts                     9. Modals
   10. Spinner                   11. Tabs
   12. Pagination and search     13. OTP step (login)
   14. Data table (manager lists)
   15. Admin table (organisation managers), small icon buttons, verified mark
   16. Side panel (drawer)
   ========================================================================== */

/* ==========================================================================
   1. BUTTONS
   One definition for every button and button-like link, driven by --btn-* tokens.
     Variants : .btn-primary  .btn-secondary (= .btn-back)  .btn-danger
                .btn-submit and .otp-submit-btn are full-width primary buttons
     Sizes    : .btn-sm (36px)   default (44px)   .btn-lg (52px)
     Shapes   : .btn-block (full width)   .btn-icon (square, icon only)
   A surface can redefine --btn-primary-* to invert the primary button (.surface-brand).
   Variant, size and shape rules share the same specificity: source order decides.
   ========================================================================== */
:root {
    --btn-min-height: 44px;
    --btn-padding: 0.5rem 1.125rem;
    --btn-font-size: 0.9375rem;
    --btn-radius: var(--ds-radius);
    --btn-gap: 0.5rem;

    --btn-primary-bg: var(--ds-brand);
    --btn-primary-bg-hover: var(--ds-brand-hover);
    --btn-primary-fg: var(--ds-text);
}

/* Brand band (yellow): the primary button inverts to dark for contrast. */
.surface-brand {
    background-color: var(--ds-brand);
    --btn-primary-bg: var(--ds-text);
    --btn-primary-bg-hover: var(--ds-text-strong);
    --btn-primary-fg: var(--ds-surface);
}

:is(.btn-primary, .btn-secondary, .btn-back, .btn-danger, .btn-submit, .otp-submit-btn) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--btn-gap);
    min-height: var(--btn-min-height);
    padding: var(--btn-padding);
    border: 1px solid var(--btn-border);
    border-radius: var(--btn-radius);
    background-color: var(--btn-bg);
    box-shadow: none;
    color: var(--btn-fg);
    font-family: var(--font-body);
    font-size: var(--btn-font-size);
    font-weight: var(--btn-weight);
    line-height: 1.25;
    text-align: center;
    text-wrap: balance;
    text-decoration: none;
    text-transform: none;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}

.btn-primary,
.btn-submit,
.otp-submit-btn {
    --btn-bg: var(--btn-primary-bg);
    --btn-bg-hover: var(--btn-primary-bg-hover);
    --btn-fg: var(--btn-primary-fg);
    --btn-border: var(--btn-primary-bg);
    --btn-border-hover: var(--btn-primary-bg-hover);
    --btn-weight: 700;
}

.btn-secondary,
.btn-back {
    --btn-bg: var(--ds-surface);
    --btn-bg-hover: var(--ds-surface-alt);
    --btn-fg: var(--ds-text);
    --btn-border: var(--ds-border-strong);
    --btn-border-hover: var(--ds-border-strong);
    --btn-weight: 600;
}

.btn-danger {
    --btn-bg: var(--ds-danger-strong);
    --btn-bg-hover: var(--ds-danger-strong-hover);
    --btn-fg: #fff;
    --btn-border: var(--ds-danger-strong);
    --btn-border-hover: var(--ds-danger-strong-hover);
    --btn-weight: 700;
}

:is(.btn-primary, .btn-secondary, .btn-back, .btn-danger, .btn-submit, .otp-submit-btn):hover:not(:disabled) {
    background-color: var(--btn-bg-hover);
    border-color: var(--btn-border-hover);
}

:is(.btn-primary, .btn-secondary, .btn-back, .btn-danger, .btn-submit, .otp-submit-btn):active:not(:disabled) {
    transform: translateY(1px);
}

:is(.btn-primary, .btn-secondary, .btn-back, .btn-danger, .btn-submit, .otp-submit-btn):disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* Icons never shrink with the label; spacing comes from the gap */
:is(.btn-primary, .btn-secondary, .btn-back, .btn-danger, .btn-submit, .otp-submit-btn) svg {
    flex-shrink: 0;
}

/* Sizes and shapes */
.btn-sm {
    --btn-min-height: 36px;
    --btn-padding: 0.375rem 0.875rem;
    --btn-font-size: 0.875rem;
    --btn-radius: var(--ds-radius-sm);
}

.btn-lg {
    --btn-min-height: 52px;
    --btn-padding: 0.75rem 1.75rem;
    --btn-font-size: 1.125rem;
}

/* Large buttons step down on phones so that a long label still fits on one line */
@media (max-width: 767px) {
    .btn-lg {
        --btn-padding: 0.75rem 1.25rem;
        --btn-font-size: 1rem;
    }
}

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

.btn-icon {
    width: var(--btn-min-height);
    padding: 0;
}

#open-suggestion-box {
    font-size: 1.1rem;
}

/* ==========================================================================
   2. LINKS
   .link-button works on <button> and <a>: an underlined text action.
   ========================================================================== */
.link-button {
    margin-left: 0.25rem;
    padding: 0;
    border: none;
    background: none;
    color: var(--ds-text);
    font: inherit;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}

.link-button:hover {
    text-decoration-thickness: 2px;
}

.link-button-muted {
    margin-left: 0;
    color: var(--ds-muted);
    font-size: 0.9rem;
    font-weight: 400;
}

.link-button-muted:hover {
    color: var(--ds-text);
}

/* ==========================================================================
   3. BADGES AND TONES
   A tone sets the --tone-* variables read by badges, pills and chips:
     .tone-neutral | brand | info | success | warning | danger | accent
   The legacy category (.badge-maintenance ...) and status (.badge-status.open ...)
   classes are aliases of a tone, so existing markup keeps working.
   ========================================================================== */
.badge,
.badge-status {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: 0.375rem;
    padding: 0.1875rem 0.625rem;
    border: 1px solid var(--tone-border, var(--ds-border));
    border-radius: var(--ds-radius-pill);
    background-color: var(--tone-bg, var(--ds-surface-alt));
    color: var(--tone-text, var(--ds-text));
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.3;
    white-space: nowrap;
}

.badge svg,
.badge-status svg {
    width: 12px;
    height: 12px;
}

.tone-neutral,
.badge-neutral,
.badge-general,
.badge-other,
.badge-lost_found,
.badge-syndic,
.badge-absence,
.badge-status.draft,
.badge-status.archived,
.badge-status.closed {
    --tone-bg: var(--ds-surface-alt);
    --tone-border: var(--ds-border);
    --tone-text: var(--ds-text);
}

.tone-brand,
.badge-brand,
.badge-primary {
    --tone-bg: var(--ds-brand-soft);
    --tone-border: var(--ds-brand);
    --tone-text: var(--ds-text-strong);
}

.tone-info,
.badge-info,
.badge-meeting,
.badge-status.processing,
.badge-status.read,
.badge-status.pending {
    --tone-bg: var(--ds-info-soft);
    --tone-border: var(--ds-info-border);
    --tone-text: var(--ds-info-text);
}

.tone-success,
.badge-success,
.badge-social,
.badge-status.published,
.badge-status.treated {
    --tone-bg: var(--ds-success-soft);
    --tone-border: var(--ds-success-border);
    --tone-text: var(--ds-success-text);
}

.tone-warning,
.badge-warning,
.badge-maintenance,
.badge-status.open {
    --tone-bg: var(--ds-warning-soft);
    --tone-border: var(--ds-warning-border);
    --tone-text: var(--ds-warning-text);
}

.tone-danger,
.badge-danger,
.badge-urgent,
.badge-alert,
.badge-outage,
.badge-notification {
    --tone-bg: var(--ds-danger-soft);
    --tone-border: var(--ds-danger-border);
    --tone-text: var(--ds-danger-text);
}

.tone-accent,
.badge-accent,
.badge-security,
.badge-status.planned,
.badge-status.answered {
    --tone-bg: var(--ds-accent-soft);
    --tone-border: var(--ds-accent-border);
    --tone-text: var(--ds-accent-text);
}

/* Initials avatar (initialsAvatar()): decorative, sized by --avatar-size (set by the container) */
.avatar-initials {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: var(--avatar-size, 40px);
    height: var(--avatar-size, 40px);
    border-radius: 50%;
    background-color: var(--ds-brand-soft);
    color: var(--ds-text-strong);
    font-size: calc(var(--avatar-size, 40px) * 0.4);
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.02em;
    user-select: none;
}

/* ==========================================================================
   4. CARDS
   ========================================================================== */
.card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    height: 100%;
    padding: 1.125rem 1.25rem;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    background-color: var(--ds-surface);
    box-shadow: var(--ds-shadow-card);
    color: inherit;
    text-decoration: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}

/* Clickable cards: links or htmx triggers */
a.card:hover,
.card[hx-get]:hover {
    border-color: var(--ds-border-strong);
    box-shadow: var(--ds-shadow-card-hover);
}

.card-top-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.75rem;
}

.card-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.0625rem;
    line-height: 1.25;
    letter-spacing: -0.01em;
}

.card-description-clamp {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    color: var(--ds-muted);
    font-size: 0.9375rem;
    line-height: 1.5;
}

.card-meta {
    margin-top: auto;
    color: var(--ds-muted);
    font-size: 0.8125rem;
}

/* Urgent alert: a soft danger card with a dismiss button */
.card.card-urgent {
    border-color: var(--ds-danger-border);
    background-color: var(--ds-danger-soft);
    box-shadow: none;
    color: var(--ds-danger-text);
    padding-right: 3.5rem;
}

.card-urgent .card-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.0625rem;
}

.card-urgent .badge-urgent {
    --tone-bg: var(--ds-danger-strong);
    --tone-border: var(--ds-danger-strong);
    --tone-text: #fff;
    font-family: var(--font-body);
}

.card-urgent p {
    font-size: 0.9375rem;
    line-height: 1.5;
}

.card-urgent-icon {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    stroke: currentColor;
}

.card-urgent-close {
    position: absolute;
    top: 0.625rem;
    right: 0.625rem;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--ds-danger-text);
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.card-urgent-close:hover {
    background-color: rgba(153, 27, 27, 0.12);
}

.card-urgent-close svg {
    width: 18px;
    height: 18px;
    stroke: currentColor;
}

/* Content outside the plan history (Essential plan): greyed out with an upgrade call to action */
.card.restricted {
    opacity: 0.55;
    pointer-events: none;
    filter: grayscale(0.3);
}

.card.restricted .restricted-overlay {
    position: absolute;
    inset: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: inherit;
    background: rgba(255, 255, 255, 0.85);
    pointer-events: auto;
}

.card.restricted .restricted-overlay a {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.5rem 1rem;
    border-radius: var(--ds-radius-pill);
    background-color: var(--ds-brand);
    color: var(--ds-text-strong);
    font-size: 0.8125rem;
    font-weight: 700;
    text-decoration: none;
    transition: background-color 0.15s ease;
}

.card.restricted .restricted-overlay a:hover {
    background-color: var(--ds-brand-hover);
}

.card.restricted .restricted-overlay svg {
    width: 14px;
    height: 14px;
}

.content-block {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 150px;
    padding: 2rem;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius);
    background: var(--ds-surface);
    color: var(--ds-muted);
    text-align: center;
}

/* ==========================================================================
   5. DASHBOARD BLOCKS
   Shared by the resident and manager dashboards.
   ========================================================================== */

/* Stacked sections in a dashboard column */
.dashboard-stack {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

/* Section card: titled panel (header + body + call to action) holding a widget */
.section-card {
    overflow: hidden;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    background: var(--ds-surface);
    box-shadow: var(--ds-shadow-card);
}

.section-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    padding: 0.875rem 1.25rem;
    border-bottom: 1px solid var(--ds-border);
}

.section-card-title {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin: 0;
    font-size: 1.0625rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}

/* The icon sits in a soft brand chip */
.section-card-title svg {
    box-sizing: content-box;
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    padding: 7px;
    border-radius: var(--ds-radius-input);
    background-color: var(--ds-brand-soft);
    color: var(--ds-text-strong);
    stroke: currentColor;
    stroke-width: 2;
}

.section-card-body {
    padding: 1rem 1.25rem;
}

.section-card-body-flush {
    padding: 0;
}

/* Cards and feeds placed in a section card become flat rows separated by hairlines */
.section-card .feed-list {
    gap: 0;
}

.section-card .card {
    height: auto;
    border: none;
    border-radius: 0;
    background-color: transparent;
    box-shadow: none;
}

.section-card .card + .card {
    border-top: 1px solid var(--ds-border);
}

.section-card a.card:hover,
.section-card .card[hx-get]:hover {
    background-color: var(--ds-surface-alt);
    border-color: var(--ds-border);
    box-shadow: none;
}

/* Call-to-action link closing a section card */
.section-cta {
    display: block;
    padding: 0.875rem 1.25rem;
    border-top: 1px solid var(--ds-border);
    color: var(--ds-text);
    font-size: 0.875rem;
    font-weight: 600;
    text-align: center;
    text-decoration: none;
    transition: background-color 0.15s ease;
}

.section-cta:hover {
    background-color: var(--ds-surface-alt);
}

/* List rows: <ul class="list-rows"><li><a|div class="list-row"> ... */
.list-rows {
    list-style: none;
}

.list-rows > li + li {
    border-top: 1px solid var(--ds-border);
}

.list-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1.25rem;
    color: inherit;
    text-decoration: none;
    transition: background-color 0.15s ease;
}

a.list-row:hover {
    background-color: var(--ds-surface-alt);
}

.list-row-main {
    flex: 1;
    min-width: 0;
}

.list-row-title {
    overflow: hidden;
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.3;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.list-row-meta {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-top: 0.125rem;
    color: var(--ds-muted);
    font-size: 0.8125rem;
}

.list-row-meta svg {
    flex-shrink: 0;
    width: 14px;
    height: 14px;
}

/* Date chip: day over month */
.date-chip {
    display: flex;
    flex: 0 0 44px;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 0.375rem 0;
    border-radius: var(--ds-radius);
    background-color: var(--tone-bg, var(--ds-brand-soft));
    color: var(--tone-text, var(--ds-text-strong));
    line-height: 1;
    text-align: center;
}

.date-chip-day {
    font-family: var(--font-display);
    font-size: 1.125rem;
    font-weight: 800;
}

.date-chip-month {
    margin-top: 3px;
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* ==========================================================================
   6. EMPTY STATES AND SKELETONS
   ========================================================================== */
.empty-state-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 2.5rem 1.5rem;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    background-color: var(--ds-surface);
    color: var(--ds-muted);
    font-size: 1rem;
    font-weight: 500;
    text-align: center;
}

.empty-state-text {
    margin: 0;
}

/* Compact empty state inside a section card */
.empty-state-compact {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 2rem 1rem;
    color: var(--ds-muted);
    text-align: center;
}

.empty-state-compact svg {
    box-sizing: content-box;
    width: 22px;
    height: 22px;
    padding: 10px;
    border-radius: 50%;
    background-color: var(--ds-surface-alt);
    stroke: currentColor;
}

.empty-state-compact p {
    margin: 0;
    font-size: 0.875rem;
}

.loading-placeholder {
    padding: 2rem;
    color: var(--ds-muted);
    text-align: center;
}

/* Skeleton: placeholder shaped like the content while an htmx fragment loads */
.skeleton-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.875rem 1.25rem;
}

.skeleton-row + .skeleton-row {
    border-top: 1px solid var(--ds-border);
}

.skeleton-lines {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 0;
}

.skeleton {
    display: block;
    border-radius: var(--ds-radius-sm);
    background: linear-gradient(90deg, var(--ds-surface-alt) 25%, #ECE8DA 50%, var(--ds-surface-alt) 75%);
    background-size: 200% 100%;
    animation: skeleton-shimmer 1.4s ease-in-out infinite;
}

.skeleton-chip {
    flex: 0 0 44px;
    height: 48px;
    border-radius: var(--ds-radius);
}

.skeleton-line {
    height: 12px;
}

.skeleton-line-short {
    width: 45%;
}

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

/* ==========================================================================
   7. CHOICE CARDS
   Large selectable options (feedback type, onboarding path):
   <button class="choice-card tone-brand"><span class="choice-card-icon">svg</span>
     <span class="choice-card-body"><span class="choice-card-title">..</span>
     <span class="choice-card-desc">..</span></span></button>
   ========================================================================== */
.choice-cards {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.choice-card {
    display: flex;
    align-items: center;
    gap: 1rem;
    width: 100%;
    padding: 1rem 1.125rem;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    background-color: var(--ds-surface);
    color: var(--ds-text);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}

.choice-card:hover {
    border-color: var(--ds-border-strong);
    box-shadow: var(--ds-shadow-card-hover);
}

.choice-card:active {
    transform: translateY(1px);
}

.choice-card-icon {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: var(--ds-radius);
    background-color: var(--tone-bg, var(--ds-brand-soft));
    color: var(--tone-text, var(--ds-text-strong));
}

.choice-card-icon svg {
    width: 24px;
    height: 24px;
}

.choice-card-body {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
}

.choice-card-title {
    font-family: var(--font-display);
    font-size: 1.0625rem;
    font-weight: 700;
}

.choice-card-desc {
    color: var(--ds-muted);
    font-size: 0.875rem;
    line-height: 1.4;
}

.choice-card-note {
    margin-top: 0.25rem;
    color: var(--ds-muted);
    font-size: 0.8125rem;
    font-style: italic;
}

/* ==========================================================================
   8. ALERTS
   <div class="alert alert-success"><p class="alert-title">..</p><p class="alert-text">..</p></div>
   Variants: alert-success | alert-info | alert-warning | alert-error (alias alert-danger).
   ========================================================================== */
.alert {
    margin-bottom: 1.5rem;
    padding: 1rem 1.25rem;
    border: 1px solid var(--alert-border, var(--ds-border));
    border-radius: var(--ds-radius);
    background-color: var(--alert-bg, var(--ds-surface-alt));
    color: var(--alert-fg, var(--ds-text));
    font-size: 0.95rem;
    font-weight: 500;
    line-height: 1.5;
    text-align: center;
}

.alert-success {
    --alert-bg: var(--ds-success-soft);
    --alert-border: var(--ds-success-border);
    --alert-fg: var(--ds-success-text);
}

.alert-info {
    --alert-bg: var(--ds-info-soft);
    --alert-border: var(--ds-info-border);
    --alert-fg: var(--ds-info-text);
}

.alert-warning {
    --alert-bg: var(--ds-warning-soft);
    --alert-border: var(--ds-warning-border);
    --alert-fg: var(--ds-warning-text);
}

.alert-error,
.alert-danger {
    --alert-bg: var(--ds-danger-soft);
    --alert-border: var(--ds-danger-border);
    --alert-fg: var(--ds-danger-text);
}

.alert-title {
    margin-bottom: 0.25rem;
    font-family: var(--font-body);
    font-size: 1rem;
    font-weight: 700;
}

.alert-text {
    font-size: 0.9rem;
    font-weight: 400;
}

/* Session expired */
.session-expired p {
    font-size: 0.95rem;
    text-align: center;
}

.session-expired a {
    color: var(--ds-text);
    font-weight: 700;
    text-decoration: underline;
    cursor: pointer;
}

.session-expired a:hover {
    text-decoration-thickness: 2px;
}

/* ==========================================================================
   9. MODALS
   <div class="modal-backdrop"> <div class="modal-panel"> header / content or body / footer
   .modal-panel-wide widens the panel for content-heavy modals.
   ========================================================================== */
.modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background-color: rgba(31, 41, 55, 0.45);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

.modal-backdrop.open {
    opacity: 1;
    pointer-events: auto;
}

.modal-panel {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 560px;
    max-height: 90vh;
    overflow: hidden;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    background-color: var(--ds-surface);
    box-shadow: var(--ds-shadow-modal);
    transform: translateY(20px);
    transition: transform 0.2s ease;
}

.modal-panel-wide {
    max-width: 1000px;
}

.modal-backdrop.open .modal-panel {
    transform: translateY(0);
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem 1.5rem;
    border-bottom: 1px solid var(--ds-border);
    background: var(--ds-surface);
}

/* A header can lead with an action (back button) before the title */
.modal-header > div:first-child {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
}

.modal-title {
    margin: 0;
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 700;
}

.modal-close-btn {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    border: none;
    border-radius: var(--ds-radius-sm);
    background: none;
    color: var(--ds-text);
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.modal-close-btn:hover {
    background-color: var(--ds-surface-alt);
}

.modal-content {
    position: relative;
    padding: 1.5rem;
    max-height: 60vh;
    overflow-y: auto;
}

.modal-body {
    flex: 1;
    padding: 1.5rem;
    overflow-y: auto;
}

/* A form wrapping a scrolling .modal-content and a .modal-footer: only the content scrolls */
.modal-form {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-height: 0;
}

.modal-form > .modal-content {
    flex: 1;
    max-height: none;
}

/* Intro text under the header */
.modal-lead {
    margin-bottom: 1.25rem;
    color: var(--ds-muted);
    font-size: 0.95rem;
    line-height: 1.5;
}

.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 0.75rem;
    padding: 1rem 1.5rem;
    border-top: 1px solid var(--ds-border);
    background: var(--ds-surface-alt);
}

/* Confirmation modal (ModalStyle.ALERT) */
.alert-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background-color: rgba(31, 41, 55, 0.45);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

.alert-modal-backdrop.open {
    opacity: 1;
    pointer-events: auto;
}

.alert-modal-content {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    width: 100%;
    max-width: 450px;
    padding: 2rem;
    border: 1px solid var(--ds-danger-border);
    border-radius: var(--ds-radius-lg);
    background-color: var(--ds-surface);
    box-shadow: var(--ds-shadow-modal);
    text-align: center;
    transform: translateY(20px);
    transition: transform 0.2s ease;
}

.alert-modal-backdrop.open .alert-modal-content {
    transform: translateY(0);
}

.alert-modal-title {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    color: var(--ds-danger-text);
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 800;
}

.alert-modal-actions {
    display: flex;
    justify-content: center;
    gap: 0.75rem;
}

/* Small phones: stack the footer actions, primary action first */
@media (max-width: 479px) {
    .modal-footer {
        flex-direction: column-reverse;
        align-items: stretch;
    }

    .modal-footer > * {
        width: 100%;
    }
}

/* ==========================================================================
   10. SPINNER
   Small rotating ring. Combined with .htmx-indicator it only shows while a request is in flight.
   ========================================================================== */
.spinner {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    color: var(--ds-muted);
    vertical-align: -0.15em;
    animation: spinner-rotate 0.7s linear infinite;
}

.spinner.htmx-indicator {
    display: none;
}

.spinner.htmx-indicator.htmx-request {
    display: inline-block;
}

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

@media (prefers-reduced-motion: reduce) {
    .spinner {
        animation-duration: 2s;
    }

    .skeleton {
        animation: none;
    }

    :is(.btn-primary, .btn-secondary, .btn-back, .btn-danger, .btn-submit, .otp-submit-btn, .choice-card) {
        transition: none;
    }
}

/* ==========================================================================
   11. TABS
   ========================================================================== */
.tabs-container {
    display: flex;
    flex-shrink: 0; /* a scroll container would otherwise collapse inside the flex column page */
    gap: 1.5rem;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--ds-border);
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

/* Hide scrollbar for Chrome/Safari/Opera */
.tabs-container::-webkit-scrollbar {
    display: none;
}

.tabs-container-extra {
    overflow-x: auto;
}

.tab-item {
    position: relative;
    display: flex;
    flex-shrink: 0; /* Prevent shrinking on small screens */
    align-items: center;
    gap: 0.5rem;
    padding-bottom: 0.75rem;
    color: var(--ds-muted);
    font-size: 0.9375rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
}

.tab-item:hover,
.tab-item.active {
    color: var(--ds-text);
}

.tab-item.active::after {
    content: '';
    position: absolute;
    bottom: -1px; /* Overlap the container border */
    left: 0;
    width: 100%;
    height: 3px;
    border-radius: 3px 3px 0 0;
    background-color: var(--ds-brand);
}

.tab-count {
    padding: 0.125rem 0.5rem;
    border-radius: var(--ds-radius-pill);
    background-color: var(--ds-surface-alt);
    color: var(--ds-text);
    font-size: 0.75rem;
    font-weight: 600;
}

.tab-item.active .tab-count {
    background-color: var(--ds-brand-soft);
}

/* ==========================================================================
   12. PAGINATION AND SEARCH
   ========================================================================== */
.pagination-wrapper {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-top: 1.5rem;
}

.pagination-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    padding: 0 0.75rem;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius);
    background-color: var(--ds-surface);
    color: var(--ds-text);
    font-size: 0.9375rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    user-select: none;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.pagination-btn:hover {
    border-color: var(--ds-border-strong);
    background-color: var(--ds-surface-alt);
}

/* Current page */
.pagination-btn.active {
    border-color: var(--ds-brand);
    background-color: var(--ds-brand);
    color: var(--ds-text-strong);
    cursor: default;
    pointer-events: none;
}

.pagination-btn.disabled {
    opacity: 0.5;
    cursor: not-allowed;
    background-color: var(--ds-surface-alt);
}

.pagination-ellipsis {
    padding: 0 0.25rem;
    color: var(--ds-muted);
    font-size: 1.2rem;
    font-weight: 800;
    letter-spacing: 2px;
}

.search-filter-container {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.search-input-wrapper {
    position: relative;
    width: 100%;
}

.search-icon {
    position: absolute;
    top: 50%;
    left: 1rem;
    width: 20px;
    height: 20px;
    color: var(--ds-muted);
    transform: translateY(-50%);
    pointer-events: none;
}

.search-input {
    width: 100%;
    padding: 0.75rem 1rem 0.75rem 3rem; /* Left padding for the icon */
    border: 1px solid var(--ds-border-strong);
    border-radius: var(--ds-radius-input);
    background-color: var(--ds-surface);
    color: var(--ds-text);
    font-family: var(--font-body);
    font-size: 1rem;
    outline: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.search-input:focus {
    border-color: var(--ds-text);
    box-shadow: 0 0 0 3px var(--ds-brand);
}

/* ==========================================================================
   13. OTP STEP (login code, rendered inside the login modal)
   ========================================================================== */
.otp-step-container {
    width: 100%;
    padding: 1.5rem 2rem 2rem;
}

.otp-info-card {
    margin-bottom: 2.5rem;
    padding: 1rem;
    border: 1px solid var(--ds-info-border);
    border-radius: var(--ds-radius);
    background-color: var(--ds-info-soft);
    text-align: center;
}

.otp-info-card p {
    margin: 0.25rem 0;
}

.otp-info-card .text-muted {
    color: var(--ds-muted);
    font-size: 0.85rem;
}

.otp-form-group {
    margin-bottom: 1.5rem;
    text-align: center;
}

.otp-label {
    display: block;
    margin-bottom: 1rem;
    color: var(--ds-text);
    font-size: 0.9rem;
    font-weight: 600;
}

.otp-input {
    display: block;
    width: 100%;
    max-width: 320px; /* Prevent an overly wide input */
    margin: 0 auto;
    padding: 0.75rem;
    border: 1px solid var(--ds-border-strong);
    border-radius: var(--ds-radius-input);
    background-color: var(--ds-surface);
    font-family: monospace;
    font-size: 2rem;
    letter-spacing: 0.6em;
    text-align: center;
    outline: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.otp-input:focus {
    border-color: var(--ds-text);
    box-shadow: 0 0 0 3px var(--ds-brand);
}

.otp-input::placeholder {
    color: var(--ds-border);
    letter-spacing: 0.6em;
}

.otp-resend-link {
    margin-top: 1.5rem;
    color: var(--ds-muted);
    font-size: 0.9rem;
    text-align: center;
}

@media (max-width: 479px) {
    .otp-step-container {
        padding: 1.25rem 1.25rem 1.5rem;
    }
}

/* ==========================================================================
   14. DATA TABLE (manager lists: feedback, events, publications)
   One component, rendered by dataTable() (design/organism/data/Table.kt).
   Desktop: one row per item. Phones (< 768px): each row becomes a block.
   ========================================================================== */
:root {
    /* Table container: sharp corners, like the admin cards. One value to tune. */
    --data-table-radius: 2px;
}

.data-table-container {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--ds-border);
    border-radius: var(--data-table-radius);
    background-color: var(--ds-surface);
    box-shadow: var(--ds-shadow-card);
}

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

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9375rem;
}

.data-table th {
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--ds-border);
    background-color: var(--ds-surface-alt);
    color: var(--ds-muted);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-align: left;
    text-transform: uppercase;
    white-space: nowrap;
}

.data-table td {
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--ds-border);
    vertical-align: middle;
}

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

.data-table tbody tr:hover {
    background-color: var(--ds-surface-alt);
}

/* Title and description: one line each on desktop, full text in the tooltip */
.data-table-title,
.data-table-description {
    max-width: 26rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.data-table-title {
    color: var(--ds-text-strong);
    font-size: 0.975rem;
    font-weight: 700;
}

.data-table-description {
    margin-top: 0.125rem;
    color: var(--ds-muted);
    font-size: 0.875rem;
}

.cell-date,
.cell-author {
    font-size: 0.875rem;
    white-space: nowrap;
}

.cell-date {
    color: var(--ds-muted);
    font-variant-numeric: tabular-nums;
}

/* Date sort control in the header */
.data-table-sort {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    cursor: pointer;
}

.data-table-sort:hover {
    color: var(--ds-text);
}

.data-table-sort svg {
    width: 14px;
    height: 14px;
}

/* Row actions: flat icon buttons, right aligned (header included) */
.cell-actions {
    width: 1%;
    white-space: nowrap;
}

.data-table th.cell-actions {
    text-align: right;
}

.data-table-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

.data-table-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--ds-border-strong);
    border-radius: var(--ds-radius-sm);
    background-color: var(--ds-surface);
    color: var(--ds-text);
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.data-table-action svg {
    width: 16px;
    height: 16px;
}

.data-table-action:hover {
    border-color: var(--ds-text);
    background-color: var(--ds-surface-alt);
}

.data-table-action.is-danger:hover {
    border-color: var(--ds-danger-border);
    background-color: var(--ds-danger-soft);
    color: var(--ds-danger-text);
}

/* Phones: the header is kept for screen readers only; each row becomes a block */
@media (max-width: 767px) {
    .data-table thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }

    .data-table,
    .data-table tbody,
    .data-table tr,
    .data-table td {
        display: block;
    }

    .data-table tr {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto auto;
        grid-template-areas:
            "title title title"
            "type type status"
            "date author actions";
        gap: 0.625rem 1rem;
        padding: 1rem 1.25rem;
        border-bottom: 1px solid var(--ds-border);
    }

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

    .data-table td {
        min-width: 0;
        padding: 0;
        border: 0;
    }

    .cell-title {
        grid-area: title;
    }

    .cell-type {
        grid-area: type;
    }

    .cell-status {
        grid-area: status;
        justify-self: end;
    }

    .cell-date {
        grid-area: date;
    }

    .cell-author {
        grid-area: author;
        justify-self: end;
    }

    .cell-actions {
        grid-area: actions;
        width: auto;
        justify-self: end;
    }

    .data-table-title,
    .data-table-description {
        max-width: none;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        white-space: normal;
    }
}

/* ==========================================================================
   15. ADMIN TABLE (organisation managers), SMALL ICON BUTTONS, VERIFIED MARK
   Same look as the data table (section 14): hairlines, muted uppercase header.
   ========================================================================== */
.admin-table-container {
    width: 100%;
    overflow-x: auto;
    border: 1px solid var(--ds-border);
    border-radius: var(--data-table-radius);
    background-color: var(--ds-surface);
    box-shadow: var(--ds-shadow-card);
}

.admin-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9375rem;
}

.admin-table th {
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--ds-border);
    background-color: var(--ds-surface-alt);
    color: var(--ds-muted);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-align: left;
    text-transform: uppercase;
    white-space: nowrap;
}

.admin-table td {
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--ds-border);
    vertical-align: middle;
}

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

.admin-table tbody tr:hover {
    background-color: var(--ds-surface-alt);
}

/* Small square icon button (topology tree actions): same look as .data-table-action */
.btn-icon-small {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--ds-border-strong);
    border-radius: var(--ds-radius-sm);
    background-color: var(--ds-surface);
    color: var(--ds-text);
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.btn-icon-small svg {
    width: 16px;
    height: 16px;
}

.btn-icon-small:hover {
    border-color: var(--ds-text);
    background-color: var(--ds-surface-alt);
}

.btn-icon-small.delete:hover {
    border-color: var(--ds-danger-border);
    background-color: var(--ds-danger-soft);
    color: var(--ds-danger-text);
}

/* Verified mark next to a name (SvgConstants.ICON_CHECK_VERIFIED) */
.verified-icon {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    margin-left: 0.25rem;
    color: var(--ds-success-solid);
    vertical-align: -3px;
}

/* ==========================================================================
   16. SIDE PANEL (drawer)
   Opened by side-panel.js. The width is a token: a screen can widen its panel.
   ========================================================================== */
:root {
    --side-panel-width: 720px;
}

.side-panel-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(31, 41, 55, 0.45);
    z-index: 100;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
}

.side-panel-overlay.open {
    opacity: 1;
    pointer-events: auto;
}

.side-panel {
    display: flex;
    flex-direction: column;
    height: 100%;
    position: fixed;
    top: 0;
    right: calc(-1 * var(--side-panel-width)); /* Start hidden */
    width: var(--side-panel-width);
    max-width: 90%;
    background-color: var(--ds-surface);
    border-left: 1px solid var(--ds-border);
    z-index: 101;
    transition: right 0.3s ease-in-out;
}

.side-panel.open {
    right: 0;
    box-shadow: -12px 0 40px rgba(31, 41, 55, 0.14);
}

.side-panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    flex-shrink: 0;
    padding: 1.25rem 2rem;
    border-bottom: 1px solid var(--ds-border);
    background-color: var(--ds-surface);
}

.side-panel-title {
    margin: 0;
    font-family: var(--font-display);
    font-size: 1.375rem;
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -0.01em;
    overflow-wrap: anywhere;
}

.side-panel-close {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-sm);
    background-color: var(--ds-surface);
    color: var(--ds-text);
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.side-panel-close:hover {
    border-color: var(--ds-border-strong);
    background-color: var(--ds-surface-alt);
}

.side-panel-content {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
    padding: 2rem;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.detail-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
}

.detail-grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
    margin-bottom: 1.5rem;
}

.wrapper-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.detail-label {
    display: block;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--text-muted);
    font-size: 0.75rem;
    margin-bottom: 0.5rem;
    letter-spacing: 0.05em;
}

.detail-value-large {
    font-size: 1.125rem;
    font-weight: 500;
    color: #1a202c;
}

.detail-value {
    word-break: break-word; /* Break long words if necessary */
    overflow-wrap: break-word; /* Standard property */
    white-space: pre-wrap; /* Preserve formatting but wrap */
    max-width: 100%; /* Ensure it doesn't overflow container */
    font-size: 1rem;
    font-weight: 500;
    line-height: 1.5;
}

.side-panel-footer {
    display: flex;
    gap: 1rem;
    flex-shrink: 0;
    padding: 1.25rem 2rem;
    border-top: 1px solid var(--ds-border);
    background-color: var(--ds-surface-alt);
}
