/* ===========================================================================
   Backend UI tokens

   Card chrome, field typography and the two-column page shell, defined once so
   every screen in the backend is identical rather than each one approximating
   the design with its own pile of utilities.

   These started life inside deposition/status-timeline.css, which meant the
   Plan Management screens could not reuse them without loading a stylesheet
   named after a component they do not have. Loaded globally from
   layouts/app.blade.php.
=========================================================================== */

:root {
    /* py-2 (16px) + 32px avatar row. Filter drawers hang below this so the
       welcome / notifications / profile top bar stays clear. */
    --cs-topbar-height: 3rem;
}

.cs-card {
    background: #ffffff;
    border: 1px solid #e9eaf0;
    border-radius: 16px;
    box-shadow: 0 1px 3px rgba(16, 24, 40, .06);
    padding: 20px 22px;
}

.cs-card-title {
    margin: 0 0 16px;
    font-size: 15px;
    font-weight: 700;
    color: #111827;
    line-height: 1.35;
}

/* Title immediately followed by helper copy (e.g. Quick Actions). */
.cs-card-title--compact {
    margin-bottom: 6px;
}

/* Row header: title on the left, summary/meta on the right. */
.cs-card-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 16px;
}

.cs-card-header .cs-card-title {
    margin-bottom: 0;
}

.cs-field-label {
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #9ca3af;
}

.cs-field-value {
    margin-top: 5px;
    font-size: 14px;
    font-weight: 600;
    color: #111827;
}

/* Fixed-width action rail: it keeps its width as the viewport grows instead of
   scaling with a fractional column. */
@media (min-width: 981px) {
    .cs-grid {
        grid-template-columns: minmax(0, 1fr) 372px;
    }
}


/* ---------------------------------------------------------------------------
   Forms

   The same eight utilities were repeated on every input across the plan
   screens, so a change to focus styling meant editing a dozen places and
   missing some. One class, one definition.
--------------------------------------------------------------------------- */
.cs-label {
    display: block;
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 600;
    color: #374151;
}

.cs-input {
    width: 100%;
    padding: 10px 14px;
    border: 1px solid #d8dbe4;
    border-radius: 10px;
    background: #ffffff;
    font-size: 14px;
    color: #111827;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.cs-input:focus {
    outline: none;
    border-color: #4f46e5;
    box-shadow: 0 0 0 3px rgba(79, 70, 229, .15);
}

.cs-input:disabled {
    background: #f8f9fc;
    color: #9ca3af;
    cursor: not-allowed;
}

select.cs-input {
    cursor: pointer;
}

/* Currency prefix. The padding lives here rather than as an extra utility on
   the input so the affordance and its spacing cannot drift apart. */
.cs-input-group {
    position: relative;
}

.cs-input-group > .cs-input {
    padding-left: 32px;
}

.cs-input-prefix {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 14px;
    display: flex;
    align-items: center;
    color: #9ca3af;
    font-size: 14px;
    pointer-events: none;
}

/* A short numeric field, sized to its content.

   `.cs-input` is width:100% because most fields sit in a grid cell; a page allowance or a
   day count stretched across a card reads as a layout mistake, so these opt out. */
.cs-input--compact {
    width: auto;
    max-width: 9rem;
}

/* Unit label attached to a field — "pages", "days", "%" — rather than floating text beside
   it. Inside the border, so the field and its unit read as one control. */
.cs-input-suffix-group {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid #d8dbe4;
    border-radius: 10px;
    background: #ffffff;
    overflow: hidden;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.cs-input-suffix-group:focus-within {
    border-color: #4f46e5;
    box-shadow: 0 0 0 3px rgba(79, 70, 229, .15);
}

/* The group owns the border and the focus ring, so the input inside drops both. */
.cs-input-suffix-group > .cs-input {
    border: 0;
    border-radius: 0;
    background: transparent;
}

.cs-input-suffix-group > .cs-input:focus {
    outline: none;
    box-shadow: none;
}

.cs-input-suffix {
    display: flex;
    align-items: center;
    padding: 0 12px;
    border-left: 1px solid #e9eaf0;
    background: #f8f9fc;
    color: #6b7280;
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
}

.cs-hint {
    margin-top: 6px;
    font-size: 12px;
    color: #9ca3af;
}

.cs-error {
    margin-top: 6px;
    font-size: 12.5px;
    color: #dc2626;
}

.cs-field-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 20px;
}

@media (min-width: 768px) {
    .cs-field-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* A titled group of fields inside a card, separated by a rule rather than by
   another nested card — nested cards read as unrelated panels. */
.cs-fieldset {
    margin-top: 26px;
    padding-top: 22px;
    border-top: 1px solid #f0f1f5;
}

.cs-fieldset-title {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    font-size: 14px;
    font-weight: 700;
    color: #111827;
}

.cs-fieldset-hint {
    margin-top: 5px;
    font-size: 12.5px;
    line-height: 1.55;
    color: #6b7280;
}

/* ---------------------------------------------------------------------------
   Buttons
--------------------------------------------------------------------------- */
.cs-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 20px;
    border: 1px solid transparent;
    border-radius: 10px;
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

/* A disabled action has to read as inert on sight: the Site Settings form ships its
   Save disabled until a switch is changed, and without this it looked identical to a
   live button that simply did nothing when pressed. */
.cs-btn:disabled {
    cursor: not-allowed;
    opacity: .5;
}

.cs-btn-primary {
    background: #4f46e5;
    color: #ffffff;
}

.cs-btn-primary:hover {
    background: #4338ca;
}

/* Hover must not brighten a button that cannot be pressed — the darker shade reads as
   a response to the pointer. */
.cs-btn-primary:disabled:hover {
    background: #4f46e5;
}

.cs-btn-secondary:disabled:hover {
    background: #ffffff;
}

.cs-btn-secondary {
    background: #ffffff;
    border-color: #d8dbe4;
    color: #374151;
}

/*
 * A button standing in a row of fields, rather than in a form footer.
 *
 * .cs-btn sizes itself from its own padding and lands at 40px, while .cs-input beside it
 * resolves to 46px (measured, not assumed — the earlier guess of ~39px was wrong and left
 * the button visibly short). align-self rather than a height: the button takes the row's
 * height from the fields, so it stays matched if their padding ever changes, and it costs
 * nothing when the row wraps and the button is alone on its line.
 *
 * Declared here rather than as a Tailwind utility because this stylesheet is served
 * directly: `self-stretch` was absent from the built CSS and would have rendered as nothing
 * until the next npm run build.
 */
.cs-btn--field {
    align-self: stretch;
}

/*
 * A standalone page whose single card should sit in the middle of the screen (the external
 * review verification step).
 *
 * Named here rather than written as a Tailwind arbitrary value. `min-h-[calc(100vh-12rem)]`
 * and `min-h-[55vh]` were both tried and both did nothing: an arbitrary value that no view
 * had used before is absent from the built stylesheet until the next `npm run build`, so the
 * class rendered as no rule at all and the card stayed pinned near the top. This file is
 * served directly, so it takes effect on refresh.
 *
 * The subtraction is guest/plain-layout.blade.php's own chrome — its py-10 twice, the logo
 * header and the footer — so this box matches <main>'s real height and centring inside it
 * lands on the middle of the viewport.
 */
.cs-centred-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: calc(100vh - 12rem);
}

/*
 * One-time-code boxes (x-backend.otp-input).
 *
 * Sized so six fit a narrow card without shrinking the digits: a code being read off a phone
 * and typed one character at a time is exactly the wrong place to save space on type size.
 */
.cs-otp-group {
    display: flex;
    justify-content: center;
    gap: 8px;
}

.cs-otp-box {
    width: 44px;
    height: 52px;
    padding: 0;
    border: 1px solid #d8dbe4;
    border-radius: 10px;
    background: #ffffff;
    text-align: center;
    font-size: 22px;
    font-weight: 700;
    color: #111827;
    font-variant-numeric: tabular-nums;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.cs-otp-box:focus {
    outline: none;
    border-color: #4f46e5;
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.18);
}

/* A filled box reads as done rather than merely occupied, so the reader can see at a glance
   how much of the code is in. */
.cs-otp-box:not(:placeholder-shown) {
    border-color: #a5b4fc;
}

@media (max-width: 400px) {
    .cs-otp-group {
        gap: 6px;
    }

    .cs-otp-box {
        width: 38px;
        height: 46px;
        font-size: 19px;
    }
}

.cs-btn-secondary:hover {
    background: #f8f9fc;
    text-decoration: none;
}

/* Link expiry: a styled dropdown rather than a native <select> — the browser's own
   dropdown chrome looks inconsistent across OSes. 5 options now (24 hours / 7 days / 15
   days / 30 days / a custom date+time), which is one reason this isn't a segmented-pill
   row: 5 short labels plus a "custom" option that needs its own date/time field no longer
   fits comfortably on one line the way 3 presets did. The selected value lives in a hidden
   input alongside the trigger button, so the surrounding form needs no change beyond
   swapping the field markup — see deposition-index.js / external-links.js. */
.cs-dropdown {
    position: relative;
}

.cs-dropdown-trigger {
    display: flex;
    width: 100%;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 14px;
    border: 1px solid #d8dbe4;
    border-radius: 10px;
    background: #ffffff;
    color: #111827;
    font-size: 14px;
    text-align: left;
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.cs-dropdown-trigger:hover {
    border-color: #b9bfcd;
}

.cs-dropdown-trigger[aria-expanded='true'] {
    border-color: #4f46e5;
    box-shadow: 0 0 0 3px rgba(79, 70, 229, .15);
}

.cs-dropdown-trigger svg {
    flex: none;
    color: #6b7280;
    transition: transform .15s ease;
}

.cs-dropdown-trigger[aria-expanded='true'] svg {
    transform: rotate(180deg);
}

.cs-dropdown-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 30;
    padding: 6px;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    background: #ffffff;
    box-shadow: 0 12px 28px rgb(15 23 42 / 12%);
}

.cs-dropdown-option {
    display: block;
    width: 100%;
    padding: 8px 10px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: #374151;
    font-size: 13px;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
}

.cs-dropdown-option:hover {
    background: #f3f4f6;
}

.cs-dropdown-option-active {
    background: #eef2ff;
    color: #4338ca;
    font-weight: 600;
}

.cs-dropdown-option-active:hover {
    background: #e0e7ff;
}

.cs-dropdown-divider {
    margin: 6px 4px;
    border-top: 1px solid #f1f2f6;
}

/* The generated link itself, shown once creation succeeds — read-only rather than an
   ordinary text input, since editing it would just produce a token nothing recognises;
   selectable/copyable is the only interaction it needs. */
.cs-link-reveal {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 10px;
    border: 1px solid #d8dbe4;
    border-radius: 10px;
    background: #f8f9fc;
}

.cs-link-reveal input {
    flex: 1;
    min-width: 0;
    border: none;
    background: transparent;
    color: #374151;
    font-size: 12.5px;
}

.cs-link-reveal input:focus {
    outline: none;
}

.cs-link-copy-btn {
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: 5px;
    padding: 6px 10px;
    border: 1px solid #d8dbe4;
    border-radius: 8px;
    background: #ffffff;
    color: #374151;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .15s ease;
}

.cs-link-copy-btn:hover {
    background: #f3f4f6;
}

.cs-link-copy-btn.cs-link-copy-btn--copied {
    border-color: #34d399;
    color: #059669;
}

.cs-form-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 26px;
    padding-top: 20px;
    border-top: 1px solid #f0f1f5;
}

/* ---------------------------------------------------------------------------
   Usage meter (free plan allowance)

   Banded on the same thresholds and the same hex values as AI confidence in the
   transcript editor — see .confidence-swatch-* in css/deposition/editor.css. The
   meaning is inverted on purpose: 90% confidence is good and green, 90% of an
   allowance spent is nearly out and red. One palette, direction given by the label.

   Named classes rather than Tailwind utilities for two reasons: the values stay
   byte-identical to the confidence bands instead of drifting to the nearest utility,
   and this file is served directly, so no rebuild stands between an edit and the page.
--------------------------------------------------------------------------- */
.cs-usage-track {
    height: 8px;
    border-radius: 9999px;
    overflow: hidden;
}

.cs-usage-bar {
    height: 8px;
    border-radius: 9999px;
    transition: width .5s ease, background-color .2s ease;
}

/* Under 50% used. #34d399 / #d1fae5 — confidence "high". */
.cs-usage--safe .cs-usage-track,
.cs-usage-track.cs-usage--safe {
    background: #d1fae5;
}

.cs-usage--safe .cs-usage-bar,
.cs-usage-bar.cs-usage--safe {
    background: #34d399;
}

.cs-usage-figure.cs-usage--safe {
    color: #047857;
}

/* 50-89% used. #f59e0b / #fef3c7 — confidence "medium". */
.cs-usage--warning .cs-usage-track,
.cs-usage-track.cs-usage--warning {
    background: #fef3c7;
}

.cs-usage--warning .cs-usage-bar,
.cs-usage-bar.cs-usage--warning {
    background: #f59e0b;
}

.cs-usage-figure.cs-usage--warning {
    color: #b45309;
}

/* 90%+ used. #ef4444 / #fee2e2 — confidence "low". */
.cs-usage--critical .cs-usage-track,
.cs-usage-track.cs-usage--critical {
    background: #fee2e2;
}

.cs-usage--critical .cs-usage-bar,
.cs-usage-bar.cs-usage--critical {
    background: #ef4444;
}

.cs-usage-figure.cs-usage--critical {
    color: #b91c1c;
}

.cs-usage-figure {
    font-size: 12px;
    font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Inline state pills
--------------------------------------------------------------------------- */
.cs-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 9999px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .02em;
}

/* Tailwind's own .hidden (plain `display:none`, no !important) loses to .cs-pill's
   `display:inline-flex` above: both are single-class selectors, so it comes down to
   source order, and this stylesheet is linked after app.css — see layouts/app.blade.php.
   That left an "Enabled"/"Disabled" pair (workflow-setting-row.blade.php) always showing
   both pills regardless of which one JS/Blade marked hidden. The compound selector here
   outranks .cs-pill on specificity alone, so it wins no matter the load order. */
.cs-pill.hidden {
    display: none;
}

/* Same tie as .cs-pill.hidden above, same fix: .cs-btn sets its own `display: inline-flex`,
   and Tailwind's plain .hidden (no !important) loses that source-order tie against it. Found
   via the AI feedback "Mark as done" button (data-ai-feedback-detail-resolve) staying visible
   with .hidden applied — the pre-existing line-feedback resolve button shares the same
   cs-btn + .hidden combination and was silently affected too. */
.cs-btn.hidden {
    display: none;
}

.cs-pill-muted {
    background: #f1f2f6;
    color: #6b7280;
}

.cs-pill-warning {
    background: #fef3c7;
    color: #b45309;
}

.cs-pill-success {
    background: #ecfdf5;
    color: #047857;
}

.cs-pill-indigo {
    background: #eef2ff;
    color: #4338ca;
}

.cs-pill-danger {
    background: #fef2f2;
    color: #b91c1c;
}

/* Radio pair presented as two equal choices rather than a checkbox whose
   unchecked state has to be inferred. */
.cs-choice-group {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
    margin-top: 16px;
}

@media (min-width: 640px) {
    .cs-choice-group {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.cs-choice {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid #e4e6ee;
    border-radius: 12px;
    background: #ffffff;
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease;
}

.cs-choice:hover {
    border-color: #c7cbd8;
    background: #fcfcfe;
}

.cs-choice:has(input:checked) {
    border-color: #4f46e5;
    background: #f5f4ff;
}

.cs-choice input {
    margin-top: 2px;
    accent-color: #4f46e5;
    cursor: pointer;
}

.cs-choice-label {
    font-size: 13.5px;
    font-weight: 600;
    color: #111827;
}

.cs-choice-hint {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    font-weight: 400;
    line-height: 1.5;
    color: #6b7280;
}

/* An icon prefix needs more room than a currency symbol. */
.cs-input-group:has(> .cs-input-prefix svg) > .cs-input,
.cs-input-group:has(> .cs-input-prefix [data-lucide]) > .cs-input {
    padding-left: 38px;
}

/* ---------------------------------------------------------------------------
   Document modal (invoice preview)

   A large, scrollable dialog for reading a document without leaving the page it
   was listed on. Wider and plainer than the confirm dialogs in standard-modal.js:
   the content is a rendered document, not a question.
--------------------------------------------------------------------------- */
.cs-doc-modal {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px 16px;
}

.cs-doc-modal.hidden {
    display: none;
}

.cs-doc-modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgb(15 23 42 / 55%);
}

.cs-doc-modal__panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 860px;
    /* Caps at the viewport so the body scrolls rather than the page behind it. */
    max-height: calc(100vh - 48px);
    overflow: hidden;
    border-radius: 16px;
    background: #ffffff;
    box-shadow: 0 24px 60px rgb(15 23 42 / 24%);
}

.cs-doc-modal__head {
    display: flex;
    flex: none;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 14px 18px;
    border-bottom: 1px solid #e5e7eb;
}

.cs-doc-modal__title {
    margin: 0;
    font-size: 15px;
    font-weight: 700;
    color: #111827;
}

.cs-doc-modal__close {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border: 0;
    border-radius: 10px;
    background: transparent;
    color: #9ca3af;
    cursor: pointer;
    transition: background-color .12s ease, color .12s ease;
}

.cs-doc-modal__close:hover {
    background: #f3f4f6;
    color: #4b5563;
}

.cs-doc-modal__close:focus-visible {
    outline: 2px solid #a5b4fc;
    outline-offset: 2px;
}

.cs-doc-modal__body {
    flex: 1;
    overflow-y: auto;
    padding: 18px;
    background: #f9fafb;
}

@media (prefers-reduced-motion: reduce) {
    .cs-doc-modal__close {
        transition: none;
    }
}

/* ---------------------------------------------------------------------------
   Search hint ("what does this search?")

   The header search box is too narrow for a placeholder that names the fields it
   matches, so the criteria live in a small popover opened from an info button
   inside the box. Click-driven, not hover: hover is unreachable on touch.
--------------------------------------------------------------------------- */
.cs-search-hint {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 8px;
    display: grid;
    place-items: center;
    width: 24px;
    border: 0;
    background: transparent;
    color: #9ca3af;
    cursor: pointer;
    transition: color .12s ease;
}

.cs-search-hint:hover,
.cs-search-hint[aria-expanded='true'] {
    color: #3730a3;
}

.cs-search-hint:focus-visible {
    outline: 2px solid #a5b4fc;
    outline-offset: 2px;
    border-radius: 6px;
}

/* Leaves room for the button so a long query does not run underneath it. */
.cs-input-group:has(> .cs-search-hint) > .cs-input {
    padding-right: 34px;
}

/* Anchored to the input group and right-aligned, so it stays on-screen when the
   search sits at the right-hand end of the header row. */
.cs-search-hint-panel {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 50;
    width: max-content;
    max-width: min(20rem, calc(100vw - 2rem));
    padding: 12px 14px;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    background: #ffffff;
    box-shadow: 0 12px 28px rgb(15 23 42 / 12%);
    text-align: left;
}

.cs-search-hint-title {
    margin: 0 0 6px;
    font-size: 12px;
    font-weight: 600;
    color: #111827;
}

.cs-search-hint-list {
    margin: 0;
    padding-left: 18px;
    list-style: disc;
    font-size: 12.5px;
    line-height: 1.6;
    color: #4b5563;
}

.cs-search-hint-note {
    margin: 8px 0 0;
    font-size: 11px;
    color: #9ca3af;
}

@media (prefers-reduced-motion: reduce) {
    .cs-search-hint {
        transition: none;
    }
}

/* ---------------------------------------------------------------------------
   Square icon action (Add New / Filters)

   Fixed 40×40 in the header — size never changes, so nothing jumps or shakes.
   On hover/focus the label appears as a tooltip *below* the control, so it cannot
   cover the search field or the neighbouring icon button.
--------------------------------------------------------------------------- */
.cs-icon-action {
    position: relative;
    display: inline-grid;
    place-items: center;
    flex: none;
    width: 40px;
    height: 40px;
    border: 1px solid #3730a3;
    border-radius: 10px;
    background: transparent;
    color: #3730a3;
    text-decoration: none;
    vertical-align: middle;
    transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}

/* Same trap as .cs-doc-modal.hidden: this file loads after Tailwind, so `display: inline-grid`
   above beats `.hidden` at equal specificity and the element stays on screen wearing a class
   that says otherwise. Every list toggles its reset control this way, and without this the
   control sat there permanently, offering to clear filters nobody had applied. */
.cs-icon-action.hidden {
    display: none;
}

.cs-icon-action:hover,
.cs-icon-action:focus-visible {
    z-index: 50;
    background: #3730a3;
    border-color: #3730a3;
    color: #ffffff;
}

.cs-icon-action:focus-visible {
    outline: 2px solid #a5b4fc;
    outline-offset: 2px;
}

.cs-icon-action__icon {
    display: grid;
    place-items: center;
}

/* Tooltip below the button — out of the header row, right-aligned so it stays
   on-screen for the trailing actions. */
.cs-icon-action__label {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 50;
    padding: 6px 10px;
    border-radius: 8px;
    background: #1f2937;
    color: #f9fafb;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.3;
    white-space: nowrap;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .12s ease, visibility .12s ease;
}

.cs-icon-action:hover .cs-icon-action__label,
.cs-icon-action:focus-visible .cs-icon-action__label {
    opacity: 1;
    visibility: visible;
}

/* Touch devices have no hover, so the tooltip would never appear. The button keeps
   its aria-label, which is what assistive tech reads there anyway. */
@media (hover: none) {
    .cs-icon-action__label {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .cs-icon-action,
    .cs-icon-action__label {
        transition: none;
    }
}

/* ---------------------------------------------------------------------------
   Filter button badge + slide-over filter panel
--------------------------------------------------------------------------- */
.cs-icon-action__badge {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 999px;
    background: #4f46e5;
    color: #ffffff;
    font-size: 11px;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}

/* Panel slides rather than appearing: the movement is what tells you it came from
   the button, and where it will go back to. Full viewport height so it reads as a
   proper sheet rather than hanging under the top bar. */
.cs-filter-panel {
    top: 0;
    bottom: 0;
    transition: transform .22s ease;
}

.cs-filter-backdrop {
    inset: 0;
}

.cs-filter-panel.is-open {
    transform: translateX(0);
}

/* Segmented choice built on a radio, so keyboard and screen-reader semantics are the
   browser's rather than reimplemented with buttons. */
.cs-filter-choice {
    display: block;
    padding: 8px 10px;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    background: #ffffff;
    color: #374151;
    font-size: 13px;
    text-align: center;
    cursor: pointer;
    transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}

.cs-filter-choice:hover {
    background: #f8f9fc;
}

.cs-filter-choice:has(input:checked) {
    border-color: #4f46e5;
    background: #eef2ff;
    color: #3730a3;
    font-weight: 600;
}

/* The radio is visually hidden, so its focus ring has to be drawn on the label. */
.cs-filter-choice:has(input:focus-visible) {
    outline: 2px solid #a5b4fc;
    outline-offset: 2px;
}

.is-disabled {
    opacity: .45;
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    .cs-filter-panel {
        transition: none;
    }
}

/* ---------------------------------------------------------------------------
   Pinned filter panel

   Pinned docks the panel beside the content instead of over it. The shell — header
   and scroll area together — is narrowed by the panel's width, so the panel never
   covers the account menu and the table simply has less room to work with.

   Width lives in one custom property because three rules depend on it agreeing.
--------------------------------------------------------------------------- */
:root {
    --cs-filter-panel-width: 24rem;
}

.cs-app-shell {
    transition: padding-right .22s ease;
}

body.has-pinned-filters .cs-app-shell {
    padding-right: var(--cs-filter-panel-width);
}

/* Pinned sits below the app header rather than over it, and drops the shadow: it is
   part of the page now, not floating above it. */
body.has-pinned-filters .cs-filter-panel {
    box-shadow: none;
    border-left: 1px solid #e5e7eb;
}

/* No backdrop when pinned — the content behind stays live and clickable. */
body.has-pinned-filters .cs-filter-backdrop {
    display: none !important;
}

.cs-filter-pin[aria-pressed="true"] {
    background: #eef2ff;
    color: #4338ca;
}

.cs-filter-pin[aria-pressed="true"] svg {
    transform: rotate(-45deg);
}

/* Too narrow to give up 24rem: pinning would leave the table unusable, so the panel
   stays an overlay regardless of the stored preference. */
@media (max-width: 1279px) {
    body.has-pinned-filters .cs-app-shell {
        padding-right: 0;
    }

    body.has-pinned-filters .cs-filter-backdrop {
        display: block !important;
    }
}

@media (prefers-reduced-motion: reduce) {
    .cs-app-shell {
        transition: none;
    }
}

/* ===========================================================================
   Toast notifications

   One system app-wide: ToastNotification (toast-notification.js). The outer
   .toast-notification is animation-only; colour lives on .toast-card--*.
=========================================================================== */

#toast-container {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: 24rem;
    pointer-events: none;
}

.toast-notification {
    width: 100%;
    max-width: 24rem;
    pointer-events: auto;
    transform: translateX(110%);
    opacity: 0;
    transition: transform 0.3s ease, opacity 0.3s ease;
}

.toast-notification.toast-enter-active {
    transform: translateX(0);
    opacity: 1;
}

.toast-notification.toast-exit-active {
    transform: translateX(110%);
    opacity: 0;
}

.toast-card {
    width: 100%;
    padding: 0.875rem 1rem;
    border-radius: 0.625rem;
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.06);
}

.toast-card--success {
    background-color: #d1fae5;
    border: 1px solid #6ee7b7;
    border-left: 4px solid #059669;
}

.toast-card--success .toast-title {
    color: #064e3b;
}

.toast-card--success .toast-message {
    color: #047857;
}

.toast-card--success .toast-icon {
    color: #059669;
}

.toast-card--error {
    background-color: #fee2e2;
    border: 1px solid #fca5a5;
    border-left: 4px solid #dc2626;
}

.toast-card--error .toast-title {
    color: #7f1d1d;
}

.toast-card--error .toast-message {
    color: #b91c1c;
}

.toast-card--error .toast-icon {
    color: #dc2626;
}

.toast-card--warning {
    background-color: #ffedd5;
    border: 1px solid #fdba74;
    border-left: 4px solid #ea580c;
}

.toast-card--warning .toast-title {
    color: #7c2d12;
}

.toast-card--warning .toast-message {
    color: #c2410c;
}

.toast-card--warning .toast-icon {
    color: #ea580c;
}

.toast-card--info {
    background-color: #eff6ff;
    border: 1px solid #bfdbfe;
    border-left: 4px solid #2563eb;
}

.toast-card--info .toast-title {
    color: #1e3a8a;
}

.toast-card--info .toast-message {
    color: #1d4ed8;
}

.toast-card--info .toast-icon {
    color: #2563eb;
}

.toast-close-btn {
    color: #6b7280;
    transition: color 0.15s ease;
}

.toast-close-btn:hover,
.toast-close-btn:focus-visible {
    color: #374151;
    outline: none;
}

@media (max-width: 640px) {
    #toast-container {
        top: 0.5rem;
        right: 0.5rem;
        left: 0.5rem;
        max-width: none;
    }

    .toast-notification {
        max-width: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .toast-notification {
        transition: none;
    }
}

/* Off-canvas navigation below 768px -----------------------------------------
 *
 * The rail is a flex column beside the content at every other width. On a phone even the
 * collapsed 84px version is a fifth of the screen spent on navigation nobody is using, so
 * below 768px it leaves the flow and slides over the page instead.
 *
 * Width is forced here because the element's own width is bound to the expanded/collapsed
 * state (w-[250px] / w-[84px]); as an overlay there is no reason to show the narrow one.
 * The state itself is read from the cs-nav-open class on <body> (layouts/app.blade.php),
 * which is why no part of this needs a second source of truth in script.
 */
@media (max-width: 767px) {
    /*
     * `body > aside.cs-sidebar`, not `body > aside`: the element carries Tailwind's
     * `relative` utility, and a class beats any number of element selectors. The plain
     * selector lost the position declaration while still winning the transform — so the
     * rail slid off screen but kept its 250px of flex space, and the page was left with
     * 125px to render in.
     */
    body > aside.cs-sidebar {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        z-index: 50;
        width: 250px !important;
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        box-shadow: 4px 0 24px rgba(16, 24, 40, 0.16);
    }

    body.cs-nav-open > aside.cs-sidebar {
        transform: none;
    }

    .cs-nav-backdrop {
        display: none;
        position: fixed;
        inset: 0;
        /* Above the z-40 topbar, below the rail it dims. */
        z-index: 45;
        background: rgba(16, 24, 40, 0.45);
    }

    body.cs-nav-open .cs-nav-backdrop {
        display: block;
    }
}

/* Inert above the breakpoint: the rail is a column there and dims nothing. */
@media (min-width: 768px) {
    .cs-nav-backdrop {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    body > aside.cs-sidebar {
        transition: none;
    }
}

/* Free-page allowance in the navigation rail ---------------------------------
 *
 * Pinned under the navigation, which is why the nav above it scrolls and this does not: the
 * figure is only useful if it is still there after a long menu.
 *
 * Colours come from .cs-usage--safe/-warning/-danger, shared with the billing card and the
 * transcript's confidence bands, so the three cannot drift apart.
 */
.cs-sidebar-usage {
    flex: none;
    /* auto, not a fixed gap: this pins the block to the foot of the rail whatever the
       navigation above it does. Relying on the nav's flex-grow to push it down put it directly
       under the logo for a user whose permissions leave the menu short or empty. */
    margin-top: auto;
    padding: 12px;
    border: 1px solid #eceef4;
    border-radius: 12px;
    background: #fbfbfd;
}

/* Collapsed to the icon rail there is only the bar, so the box should not dwarf it. */
.cs-sidebar-usage:has(.cs-sidebar-usage__track:only-child) {
    padding: 10px 8px;
}

.cs-sidebar-usage__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 7px;
}

.cs-sidebar-usage__label {
    font-size: 12px;
    font-weight: 700;
    color: #374151;
}

.cs-sidebar-usage__track {
    width: 100%;
}

.cs-sidebar-usage__count {
    margin: 7px 0 0;
    font-size: 11.5px;
    font-weight: 500;
    color: #6b7280;
    font-variant-numeric: tabular-nums;
}

/* The one line that says how much room is left, in the band's own colour. */
.cs-sidebar-usage__remaining {
    margin: 1px 0 0;
    font-size: 11.5px;
    font-weight: 700;
}

.cs-sidebar-usage__remaining.cs-usage--safe {
    color: #047857;
}

.cs-sidebar-usage__remaining.cs-usage--warning {
    color: #b45309;
}

/* `critical`, which is what FreePlanService::band() returns — not `danger`, which exists in
   this file for another component and would silently never match. */
.cs-sidebar-usage__remaining.cs-usage--critical {
    color: #b91c1c;
}

.cs-sidebar-usage__link {
    display: block;
    margin-top: 9px;
    padding: 6px 8px;
    border: 1px solid #d8dbe4;
    border-radius: 8px;
    color: #4f46e5;
    font-size: 11.5px;
    font-weight: 700;
    text-align: center;
}

.cs-sidebar-usage__link:hover {
    background: #eef2ff;
    border-color: #c7d2fe;
}

/*
 * The remove control on a participant row (deposition/edit.blade.php).
 *
 * Sized to the text inputs beside it rather than to its own icon: the fields are
 * px-4 py-2.5 plus a 1px border, which is 38px tall, and an icon button left at its natural
 * 32px sat with its centre three pixels below theirs — close enough to look like a mistake
 * rather than a choice.
 *
 * A named class, not h-[38px]: this project has repeatedly found Tailwind arbitrary values
 * missing from the built stylesheet, and a rule that silently produces nothing is exactly
 * the bug being fixed here.
 */
.cs-participant-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    /* border-box, stated rather than assumed: the 38px below is the height the fields beside
       it measure, and without this the 1px border would push the button to 40px and undo the
       alignment it is here to hold. */
    box-sizing: border-box;
    width: 38px;
    height: 38px;
    /* The same hairline as the text inputs (Tailwind's border-gray-300), so the control reads
       as a field-height button in the row rather than a bare icon floating beside two boxes. */
    border: 1px solid #d1d5db;
    border-radius: 10px;
    background: #ffffff;
    color: #dc2626;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.cs-participant-remove:hover {
    border-color: #fca5a5;
    background: #fef2f2;
    color: #b91c1c;
}

.cs-participant-remove:focus-visible {
    outline: 2px solid #f87171;
    outline-offset: 2px;
}

/*
 * Holds the button level with the inputs instead of with the bottom of the row.
 *
 * The row is align-items: flex-start so that a validation message under one field cannot
 * drag the button down with it — under the previous flex-end it ended up BELOW the error
 * text, level with nothing at all. This spacer stands in for the labels the other columns
 * have, so the button starts where their inputs start.
 */
.cs-participant-remove-cell {
    display: flex;
    flex: none;
    flex-direction: column;
}

.cs-participant-remove-cell::before {
    content: '';
    display: block;
    /* The label's line-height (20px) plus the inputs' mt-1 (4px). */
    height: 24px;
}

/*
 * backend-ui.css is loaded AFTER Tailwind, so on equal specificity the rule above wins over
 * .hidden and the cell stays visible when something asks it not to be. The create screen
 * hides the first participant's delete button exactly that way — there is nothing to remove
 * when there is only one row.
 */
.cs-participant-remove-cell.hidden,
.cs-participant-remove-cell[hidden] {
    display: none;
}

