/* core/css/widgets.css — Shared form widget styles
   Prefix: fw- (form widget)
   Used by: core/templates/core/forms/widgets/ */

/* ── Field Wrapper ── */

.fw-field {
    display: block;
}

/* ── Required Marker ── */

.fw-required {
    color: rgb(var(--color-destructive-500));
}

/* ── Choice Input (MD3 checkbox / radio) ──
   Checkbox: 18dp container, 2dp corner radius, 2dp outline border; checked
   fills with primary and shows an on-primary checkmark. Radio: 20dp ring;
   selected shows a primary ring with a primary inner dot (radial gradient —
   ::before/::after are reserved/reset for third-party interop below). */

.fw-choice-input {
    appearance: none !important;
    -webkit-appearance: none !important;
    flex-shrink: 0;
    border: 2px solid rgb(var(--md-sys-color-on-surface-variant)) !important;
    background-color: transparent !important;
    cursor: pointer;
    outline: none;
    transition: background-color 150ms var(--md-sys-motion-easing-standard),
                border-color 150ms var(--md-sys-motion-easing-standard);
}

.fw-choice-input::before,
.fw-choice-input::after {
    display: none !important;
    content: none !important;
}

.fw-choice-input--checkbox {
    width: 1.125rem !important;
    height: 1.125rem !important;
    border-radius: 2px !important;
}

.fw-choice-input--radio {
    width: 1.25rem !important;
    height: 1.25rem !important;
    border-radius: 50% !important;
}

.fw-choice-input--checkbox:checked {
    background-color: rgb(var(--md-sys-color-primary)) !important;
    border-color: rgb(var(--md-sys-color-primary)) !important;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='3' stroke='white'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='m4.5 12.75 6 6 9-13.5'/%3E%3C/svg%3E") !important;
    background-repeat: no-repeat !important;
    background-position: center !important;
    background-size: 0.75rem !important;
}

/* Selected radio: primary ring + centered primary dot (10dp of the 20dp). */
.fw-choice-input--radio:checked {
    border-color: rgb(var(--md-sys-color-primary)) !important;
    background: radial-gradient(circle,
        rgb(var(--md-sys-color-primary)) 0 31%,
        transparent 34%) !important;
}

.fw-choice-input:focus-visible {
    outline: 2px solid rgb(var(--md-sys-color-primary));
    outline-offset: 2px;
}

.fw-choice-input:disabled {
    border-color: rgb(var(--md-sys-color-on-surface) / 0.38) !important;
    cursor: default;
}

/* ── Choice Option Label (shared by single checkbox, multi-checkbox, radio) ──
   Plain MD3 list rows — the control and a body-large label, state layer on
   hover, no pill/glass container. */

.fw-choice-label {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0.75rem;
    border-radius: var(--md-sys-shape-corner-extra-small, 4px);
    cursor: pointer;
    min-width: 0;
    transition: background-color 150ms var(--md-sys-motion-easing-standard);
}

.fw-choice-label:hover {
    background-color: rgb(var(--md-sys-color-on-surface) / 0.08);
}

/* Larger padding for standalone single-checkbox */
.fw-checkbox-label {
    padding: 0.75rem;
}

/* In single-checkbox context, the text container fills remaining space */
.fw-checkbox-label .fw-choice-text {
    flex: 1;
}

.fw-choice-text {
    font-size: 1rem;
    color: rgb(var(--md-sys-color-on-surface));
}

/* Tighter rows inside grids so narrow cells (e.g. the 7-column weekday
   picker) don't clip their labels. */
.fw-checkbox-grid .fw-choice-label {
    padding: 0.375rem 0.375rem;
    gap: 0.5rem;
}

/* Truncate text when inside a grid (multi-choice context) */
.fw-checkbox-grid .fw-choice-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fw-choice-name {
    display: block;
    font-size: 1rem;
    color: rgb(var(--md-sys-color-on-surface));
}

.fw-choice-help {
    display: block;
    margin-top: 0.125rem;
    font-size: 0.75rem;
    line-height: 1rem;
    color: rgb(var(--md-sys-color-on-surface-variant));
}

/* ── Choice Grid ── */

/* Column count adapts to the grid's own rendered width, not the viewport —
   this widget gets mounted in containers of wildly different widths (a full
   page, a narrow modal drawer, a sidebar panel) that have no relation to the
   viewport size a fixed media-query breakpoint would key off of. Falls back
   to viewport-based breakpoints for browsers without container query
   support (behavior identical to the previous implementation).
   Containment lives on the .fw-field wrapper, not the grid itself — a
   container query can't size an element against a containment context the
   element itself establishes, it only sees ancestor containers. */
.fw-field:has(.fw-checkbox-grid) {
    container-type: inline-size;
}

.fw-checkbox-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.5rem;
}

@container (min-width: 400px) {
    .fw-checkbox-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@container (min-width: 640px) {
    .fw-checkbox-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

@supports not (container-type: inline-size) {
    @media (min-width: 640px) {
        .fw-checkbox-grid {
            grid-template-columns: repeat(2, 1fr);
        }
    }

    @media (min-width: 1024px) {
        .fw-checkbox-grid {
            grid-template-columns: repeat(3, 1fr);
        }
    }
}

/* 7-column layout for weekday selection (Mon–Sun) */
.fw-checkbox-grid--7col {
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
}

@media (min-width: 1024px) {
    .fw-checkbox-grid--7col {
        grid-template-columns: repeat(7, 1fr);
    }
}

/* ── Password ──
   .fw-password-wrap / .fw-password-input remain in the markup purely as JS
   hooks for fwTogglePassword; the field chrome is the shared fw-md3 outlined
   anatomy and the toggle button is a .fw-md3-trailing-btn. */

.fw-password-eye {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
}

.fw-password-eye svg {
    width: 1.25rem;
    height: 1.25rem;
}

/* ── Hidden Utility ── */

.fw-hidden {
    display: none;
}

/* Visually hidden but still focusable/participates in layout flow enough for
   native constraint validation — unlike display:none, this lets a `required`
   select still be validated and (if invalid) focused by the browser on
   submit instead of throwing "not focusable" and silently blocking it. */
.fw-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;
}

/* ── Widget Container (complex HTMX widgets) ── */

.fw-widget-container {
    position: relative;
}

.fw-widget-container--inactive {
    opacity: 0.4;
    pointer-events: none;
    user-select: none;
    transition: opacity 300ms;
}

/* ── Toggle (MD3 switch) ──
   52x32dp track. Unselected: surface-container-highest fill, 2dp outline
   border, 16dp on-surface-variant handle. Selected: primary fill, handle
   grows to 24dp in on-primary and slides right. Plain label row, no pill. */

.fw-toggle-label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.5rem 0;
    cursor: pointer;
}

.fw-toggle-name {
    font-size: 1rem;
    color: rgb(var(--md-sys-color-on-surface));
}

.fw-toggle-wrapper {
    position: relative;
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}

.fw-toggle-input {
    position: absolute;
    width: 0 !important;
    height: 0 !important;
    opacity: 0 !important;
    appearance: none !important;
}

.fw-toggle-track {
    position: relative;
    width: 3.25rem;
    height: 2rem;
    box-sizing: border-box;
    border-radius: 9999px;
    border: 2px solid rgb(var(--md-sys-color-outline));
    background-color: rgb(var(--md-sys-color-surface-container-highest));
    transition: background-color 200ms var(--md-sys-motion-easing-standard),
                border-color 200ms var(--md-sys-motion-easing-standard);
}

.fw-toggle-track::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 0.375rem;
    width: 1rem;
    height: 1rem;
    background-color: rgb(var(--md-sys-color-on-surface-variant));
    border-radius: 9999px;
    transform: translateY(-50%);
    transition: transform 200ms var(--md-sys-motion-easing-standard),
                width 200ms var(--md-sys-motion-easing-standard),
                height 200ms var(--md-sys-motion-easing-standard),
                background-color 200ms var(--md-sys-motion-easing-standard);
}

.fw-toggle-input:checked + .fw-toggle-track {
    background-color: rgb(var(--md-sys-color-primary));
    border-color: rgb(var(--md-sys-color-primary));
}

/* 24dp handle, 4dp from the track's right inner edge. */
.fw-toggle-input:checked + .fw-toggle-track::before {
    width: 1.5rem;
    height: 1.5rem;
    background-color: rgb(var(--md-sys-color-on-primary));
    transform: translate(0.875rem, -50%);
}

.fw-toggle-input:focus-visible + .fw-toggle-track {
    outline: 2px solid rgb(var(--md-sys-color-primary));
    outline-offset: 2px;
}

/* ── Search Widget — Shared (single select search + multi select chips) ── */

.fw-search-wrap {
    /* token definitions — light (self-contained so widget works outside .fw-sss-input) */
    --md-sys-color-surface-container-low: var(--color-surface-100);
    --md-sys-color-outline-variant: var(--color-surface-200);
    --md-sys-color-on-surface: var(--color-surface-900);
    --md-sys-color-on-surface-variant: var(--color-surface-600);
    --md-sys-color-primary: var(--color-primary-600);

    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: rgb(var(--md-sys-color-surface-container-low));
    border: 1px solid rgb(var(--md-sys-color-outline-variant));
    border-radius: 9999px !important;
    padding: 0 1.25rem;
    height: 38px;
    line-height: 1.5;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.fw-search-wrap:focus-within {
    border-color: rgb(var(--md-sys-color-primary)) !important;
    box-shadow: 0 0 0 3px rgb(var(--md-sys-color-primary) / 0.15) !important;
}

.fw-search-icon-wrap {
    display: flex !important;
    align-items: center;
    flex-shrink: 0;
    color: rgb(var(--md-sys-color-on-surface-variant));
    pointer-events: none;
    position: static !important;
    transform: none !important;
    left: auto !important;
    top: auto !important;
    z-index: auto !important;
    background: none !important;
    border: none !important;
    padding: 0 !important;
    margin: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
}

.fw-search-icon {
    display: block !important;
    width: 1.25rem !important;
    height: 1.25rem !important;
    color: inherit !important;
    background: none !important;
    border: none !important;
    padding: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
}

.fw-search-input {
    flex: 1 !important;
    min-width: 0 !important;
    width: auto !important;
    border: none !important;
    outline: none !important;
    background: transparent !important;
    font-size: 0.9375rem !important;
    color: rgb(var(--md-sys-color-on-surface)) !important;
    font-family: inherit !important;
    padding: 0 !important;
    height: auto !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    transition: none !important;
}

.fw-search-input::placeholder {
    color: rgb(var(--md-sys-color-on-surface-variant));
    font-weight: 400;
}

.fw-search-input:hover,
.fw-search-input:focus {
    border-color: transparent !important;
    box-shadow: none !important;
}

.fw-search-dropdown {
    position: absolute;
    z-index: 100;
    left: 0;
    right: 0;
    margin-top: 0.5rem;
    min-width: 14rem;
    max-height: 15rem;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: rgb(var(--md-sys-color-surface-container-low));
    border: 1px solid rgb(var(--md-sys-color-outline-variant));
    border-radius: 12px;
    box-shadow: 0 8px 24px rgb(0 0 0 / 0.12);
    scrollbar-width: thin;
    scrollbar-color: rgb(var(--md-sys-color-outline-variant)) transparent;
}

.fw-search-divider {
    margin: 0;
    border-top: 1px solid rgb(var(--md-sys-color-outline-variant));
}

.fw-search-item {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 0.5rem 1rem;
    text-align: left;
    font-size: 0.9375rem;
    color: rgb(var(--md-sys-color-on-surface));
    background: none;
    border: none;
    cursor: pointer;
    transition: background 0.1s;
    white-space: nowrap;
}

.fw-search-item:hover {
    background: rgb(var(--md-sys-color-on-surface) / 0.06);
}

/* Choice dropdown: the currently selected option is excluded from its own
   panel (there's nothing useful about being able to "pick" what's already
   picked) rather than just highlighted. Removing it can leave a dangling
   divider on either side, depending on whether it was the first item (no
   leading divider to begin with — hide the one trailing it instead) or a
   middle/last item (hide its own leading divider, keep the trailing one as
   the separator for its former neighbors). */
.fw-cdd-panel .fw-search-item[aria-selected="true"] {
    display: none;
}

.fw-cdd-panel .fw-search-divider:has(+ .fw-search-item[aria-selected="true"]) {
    display: none;
}

.fw-cdd-panel .fw-search-item[aria-selected="true"]:first-child + .fw-search-divider {
    display: none;
}

.fw-search-item-icon {
    display: none;
}

.fw-search-item-text {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fw-search-empty {
    padding: 0.75rem 1rem;
    font-size: 0.9375rem;
    color: rgb(var(--md-sys-color-on-surface-variant));
    font-style: italic;
    text-align: center;
}

/* ── Single Select Search ── */

.fw-sss-input {
    position: relative;
    /* token definitions — light; cascade to trigger, panel, results */
    --md-sys-color-surface-container-low: var(--color-surface-100);
    --md-sys-color-outline-variant: var(--color-surface-200);
    --md-sys-color-on-surface: var(--color-surface-900);
    --md-sys-color-on-surface-variant: var(--color-surface-600);
    --md-sys-color-primary: var(--color-primary-600);
    --fw-sss-panel-bg: var(--color-surface-100);
}

@media (prefers-color-scheme: dark) {
    .fw-sss-input,
    .fw-search-wrap {
        --md-sys-color-surface-container-low: var(--color-surface-800);
        --md-sys-color-outline-variant: var(--color-surface-700);
        --md-sys-color-on-surface: var(--color-surface-100);
        --md-sys-color-on-surface-variant: var(--color-surface-400);
        --md-sys-color-primary: var(--color-primary-400);
        --fw-sss-panel-bg: var(--color-surface-950, 8 8 8);
    }
}

/* Trigger — a bare flex row; all field chrome (background, outline, focus
   and open states) comes from the shared .fw-md3-control / .fw-md3-outline
   anatomy, never from the trigger itself. */
.fw-sss-trigger {
    white-space: nowrap;
    outline: none !important;
}

.fw-sss-trigger:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.fw-sss-trigger-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: left;
}

/* Chevron icon — rotates when panel is open */
.fw-sss-chevron {
    width: 1rem !important;
    height: 1rem !important;
    color: rgb(var(--md-sys-color-on-surface-variant));
    flex-shrink: 0 !important;
    transition: transform 0.2s ease;
    display: block !important;
    background: none !important;
    border: none !important;
    padding: 0 !important;
    box-shadow: none !important;
    border-radius: 0 !important;
}

.fw-sss-trigger[aria-expanded="true"] .fw-sss-chevron {
    transform: rotate(180deg);
}

/* Clear button (replaces chevron when an item is selected) */
.fw-sss-trigger-clear {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    background: none !important;
    border: none !important;
    padding: 0 !important;
    margin: 0 !important;
    cursor: pointer;
    color: inherit;
    transition: color 0.15s;
    border-radius: 0 !important;
    box-shadow: none !important;
    line-height: 0;
}

.fw-sss-trigger-clear svg {
    width: 1rem;
    height: 1rem;
    display: block;
}

.fw-sss-trigger-clear:hover {
    color: rgb(var(--md-sys-color-on-surface)) !important;
    background: none !important;
}

/* Panel (the dropdown) */
.fw-sss-panel {
    position: absolute;
    top: calc(100% + 0.5rem);
    left: 0;
    z-index: 100;
    min-width: 14rem;
    max-width: 22rem;
    background: rgb(var(--fw-sss-panel-bg));
    border: 1px solid rgb(var(--md-sys-color-outline-variant));
    border-radius: 12px;
    box-shadow: 0 8px 24px rgb(0 0 0 / 0.12);
    overflow: hidden;
}

/* Choice dropdown panel — no search bar. Per MD3 exposed dropdowns the menu
   is at least as wide as its field and left-aligned to it; max-content lets
   a long option stretch it a bit further. */
.fw-cdd-panel {
    min-width: 100%;
    max-width: 22rem;
    width: max-content;
}

/* Search bar inside panel */
.fw-sss-panel-search {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0 0.875rem;
    border-bottom: 1px solid rgb(var(--md-sys-color-outline-variant));
}

.fw-sss-panel-search-icon {
    width: 1rem !important;
    height: 1rem !important;
    flex-shrink: 0;
    color: rgb(var(--md-sys-color-on-surface-variant));
    display: block !important;
    background: none !important;
    border: none !important;
    padding: 0 !important;
    box-shadow: none !important;
    border-radius: 0 !important;
}

.fw-sss-panel-input {
    flex: 1 !important;
    border: none !important;
    outline: none !important;
    background: transparent !important;
    font-size: 0.875rem !important;
    font-family: inherit !important;
    color: rgb(var(--md-sys-color-on-surface)) !important;
    padding: 0 !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    height: auto !important;
    width: auto !important;
}

.fw-sss-panel-input::placeholder {
    color: rgb(var(--md-sys-color-on-surface-variant));
}

.fw-sss-panel-input:hover,
.fw-sss-panel-input:focus {
    border-color: transparent !important;
    box-shadow: none !important;
}

/* Items list */
.fw-sss-results {
    padding: 0.375rem 0;
    max-height: 14rem;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: rgb(var(--md-sys-color-outline-variant)) transparent;
}

/* ── Multi Select Chips ── */

.fw-msc-compact-input {
    position: relative;
}

/* MD3 input chips: 32dp tall, 8dp corners, 1dp outline, label-large text
   with a remove icon — wrapping inline instead of the old full-width rows. */
.fw-msc-chips {
    margin-top: 0.75rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.fw-msc-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    width: auto;
    height: 2rem;
    margin: 0;
    padding: 0 1rem 0 0.5rem;
    text-align: left;
    font-size: 0.875rem;
    font-weight: 500;
    color: rgb(var(--md-sys-color-on-surface));
    background: transparent;
    border: 1px solid rgb(var(--md-sys-color-outline));
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 150ms var(--md-sys-motion-easing-standard);
}

.fw-msc-chip:hover {
    background-color: rgb(var(--md-sys-color-on-surface) / 0.08);
}

.fw-msc-chip-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 1.125rem;
    height: 1.125rem;
    margin: 0;
    color: rgb(var(--md-sys-color-on-surface-variant));
    background: none;
    border: none;
    border-radius: 0;
    transition: color 150ms var(--md-sys-motion-easing-standard);
}

.fw-msc-chip-icon svg {
    width: 1.125rem;
    height: 1.125rem;
}

.fw-msc-chip:hover .fw-msc-chip-icon {
    color: rgb(var(--md-sys-color-on-surface));
}

.fw-msc-chip-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 18rem;
}

/* ── Segmented Control ──
   Keeps the original sliding-thumb design (a deliberate departure from MD3
   segmented buttons, by design decision) but dressed as an outlined field:
   same 56px height, same outline token/hover/error border treatment and 4px
   corners as .fw-md3-outline, transparent track. The thumb is glassy — a
   low-alpha primary tint over a backdrop blur with a primary hairline —
   and the selected label carries the primary accent. */

.fw-segmented-control {
    position: relative !important;
    display: inline-flex !important;
    height: 3.5rem !important;
    width: 180px !important;
    flex-shrink: 0 !important;
    border-radius: var(--md-sys-shape-corner-extra-small, 4px) !important;
    border: 1px solid rgb(var(--md-sys-color-outline)) !important;
    background: transparent !important;
    padding: 4px !important;
    box-sizing: border-box !important;
    user-select: none !important;
    transition: border-color 200ms var(--md-sys-motion-easing-standard);
}

/* Hover/error borders mirror .fw-md3-outline so the control never stands out
   from the outlined fields sharing its row. */
.fw-segmented-control:hover {
    border-color: rgb(var(--md-sys-color-on-surface)) !important;
}

.fw-md3--error .fw-segmented-control,
.fw-md3--error .fw-segmented-control:hover {
    border-color: rgb(var(--md-sys-color-error)) !important;
}

.fw-segmented-radio {
    position: absolute !important;
    width: 0 !important;
    height: 0 !important;
    opacity: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    pointer-events: none !important;
}

.fw-segmented-track {
    position: relative !important;
    width: 100% !important;
    height: 100% !important;
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    margin: 0 !important;
    padding: 0 !important;
    border: none !important;
    background: transparent !important;
}

.fw-segmented-slider {
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    width: 50% !important;
    height: 100% !important;
    /* Container radius minus its 4px padding would be negative; a hair of
       rounding keeps the thumb from looking sharper than the outline. */
    border-radius: calc(var(--md-sys-shape-corner-extra-small, 4px) - 2px) !important;
    /* Glass thumb: a whisper of primary over a backdrop blur, edged with a
       primary hairline. Safe over any surface — including glass panels —
       because nothing here is opaque. */
    background: rgb(var(--md-sys-color-primary) / 0.08) !important;
    border: 1px solid rgb(var(--md-sys-color-primary) / 0.25) !important;
    -webkit-backdrop-filter: blur(8px) saturate(1.3) !important;
    backdrop-filter: blur(8px) saturate(1.3) !important;
    box-shadow: none !important;
    transition: transform 0.2s var(--md-sys-motion-easing-standard, cubic-bezier(0.4, 0, 0.2, 1)) !important;
    z-index: 1 !important;
    box-sizing: border-box !important;
}

.fw-segmented-label {
    flex: 1 1 0% !important;
    width: auto !important;
    min-width: 0 !important;
    max-width: none !important;
    height: 100% !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    font-size: 0.875rem !important;
    font-weight: 600 !important;
    color: rgb(var(--md-sys-color-on-surface-variant)) !important;
    cursor: pointer !important;
    z-index: 2 !important;
    transition: color 0.15s ease !important;
    text-align: center !important;
    margin: 0 !important;
    padding: 0 !important;
    float: none !important;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    line-height: normal !important;
}

.fw-segmented-radio--remote:checked ~ .fw-segmented-track .fw-segmented-slider {
    transform: translateX(0) !important;
}

.fw-segmented-radio--local:checked ~ .fw-segmented-track .fw-segmented-slider {
    transform: translateX(100%) !important;
}

/* Neutral surface thumb; the selection is voiced by the primary label. */
.fw-segmented-radio--remote:checked ~ .fw-segmented-track .fw-segmented-label--remote,
.fw-segmented-radio--local:checked ~ .fw-segmented-track .fw-segmented-label--local {
    color: rgb(var(--md-sys-color-primary)) !important;
}

.fw-segmented-control--locked .fw-segmented-label--remote {
    opacity: 0.38 !important;
    cursor: default !important;
}

/* ── Segmented Control (choices variant: one segment per choice, up to 5) ── */

.fw-segmented-control--choices {
    width: auto !important;
}

.fw-segmented-control--choices .fw-segmented-label {
    padding: 0 16px !important;
    white-space: nowrap !important;
}

.fw-segmented-control--choices .fw-segmented-slider {
    width: calc(100% / var(--fw-seg-count, 2)) !important;
}

.fw-segmented-control--choices .fw-segmented-radio:checked + .fw-segmented-label {
    color: rgb(var(--md-sys-color-primary)) !important;
}

.fw-segmented-control--choices .fw-segmented-track:has(.fw-segmented-radio:nth-of-type(1):checked) .fw-segmented-slider {
    transform: translateX(0) !important;
}

.fw-segmented-control--choices .fw-segmented-track:has(.fw-segmented-radio:nth-of-type(2):checked) .fw-segmented-slider {
    transform: translateX(100%) !important;
}

.fw-segmented-control--choices .fw-segmented-track:has(.fw-segmented-radio:nth-of-type(3):checked) .fw-segmented-slider {
    transform: translateX(200%) !important;
}

.fw-segmented-control--choices .fw-segmented-track:has(.fw-segmented-radio:nth-of-type(4):checked) .fw-segmented-slider {
    transform: translateX(300%) !important;
}

.fw-segmented-control--choices .fw-segmented-track:has(.fw-segmented-radio:nth-of-type(5):checked) .fw-segmented-slider {
    transform: translateX(400%) !important;
}

.fw-segmented-control--locked.fw-segmented-control--choices .fw-segmented-label {
    opacity: 0.38 !important;
    cursor: default !important;
}

/* The choices variant disables every segment when locked, so it takes the
   full MD3 disabled-field outline (the on/off pair keeps one live segment
   and therefore the regular border). */
.fw-segmented-control--locked.fw-segmented-control--choices,
.fw-segmented-control--locked.fw-segmented-control--choices:hover {
    border-color: rgb(var(--md-sys-color-on-surface) / 0.12) !important;
}

/* ── MD3 Outlined Field (pilot: select widget) ──
   Tokens are scoped to .fw-md3 for now, mirroring the .fw-search-wrap /
   .fw-sss-input pattern; hoist to :root once the remaining widgets migrate.
   The outline is a fieldset/legend so the label notch is a real border gap —
   no background patch behind the label, safe over glass surfaces. */

.fw-md3 {
    --md-sys-color-primary: var(--color-primary-600);
    --md-sys-color-on-primary: 255 255 255;
    --md-sys-color-error: var(--color-destructive-600);
    --md-sys-color-on-surface: var(--color-surface-900);
    --md-sys-color-on-surface-variant: var(--color-surface-600);
    --md-sys-color-outline: var(--color-surface-400);
    /* Approximations of the secondary-container pair from the phoxtail
       palette (no dedicated secondary hue exists yet). */
    --md-sys-color-secondary-container: var(--color-primary-100);
    --md-sys-color-on-secondary-container: var(--color-primary-900);
    --md-sys-color-surface-container-highest: var(--color-surface-200);
    --md-sys-color-surface-container-low: var(--color-surface-100);
    --md-sys-color-outline-variant: var(--color-surface-200);
    --md-sys-motion-easing-standard: cubic-bezier(0.2, 0, 0, 1);
    --md-sys-shape-corner-extra-small: 4px;
}

@media (prefers-color-scheme: dark) {
    .fw-md3 {
        --md-sys-color-primary: var(--color-primary-400);
        --md-sys-color-on-primary: var(--color-primary-950, 0 0 0);
        --md-sys-color-error: var(--color-destructive-400);
        --md-sys-color-on-surface: var(--color-surface-100);
        --md-sys-color-on-surface-variant: var(--color-surface-400);
        --md-sys-color-outline: var(--color-surface-600);
        --md-sys-color-secondary-container: var(--color-primary-900);
        --md-sys-color-on-secondary-container: var(--color-primary-100);
        --md-sys-color-surface-container-highest: var(--color-surface-700);
        --md-sys-color-surface-container-low: var(--color-surface-800);
        --md-sys-color-outline-variant: var(--color-surface-700);
    }
}

.fw-md3-outlined {
    position: relative;
    display: flex;
    align-items: center;
    /* MD3 default field height is 56dp; drop to 40px if a -2 density is
       preferred for dense forms. */
    height: 56px;
}

/* Structural props carry !important as armor against host-app admin CSS
   (Wagtail restyles input/select/textarea/label/legend/fieldset globally,
   sometimes with attribute selectors that out-rank a single class). State
   rules (focus, error, disabled) target the sibling outline/label, so they
   are unaffected by these. */
.fw-md3-control {
    appearance: none !important;
    -webkit-appearance: none !important;
    width: 100% !important;
    height: 100%;
    margin: 0 !important;
    padding: 0 1rem !important;
    border: none !important;
    outline: none !important;
    box-shadow: none !important;
    background: transparent !important;
    font-size: 1rem !important;
    font-family: inherit !important;
    font-weight: 400 !important;
    line-height: normal;
    color: rgb(var(--md-sys-color-on-surface)) !important;
    border-radius: var(--md-sys-shape-corner-extra-small) !important;
    box-sizing: border-box !important;
}

select.fw-md3-control {
    cursor: pointer;
}

/* MD3 fields don't show native number spinners; the trailing area stays clean. */
input.fw-md3-control[type="number"] {
    -moz-appearance: textfield;
}

input.fw-md3-control[type="number"]::-webkit-outer-spin-button,
input.fw-md3-control[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* Reserve room for the trailing icon (24dp icon + 12dp inset per spec). */
.fw-md3-outlined:has(.fw-md3-trailing, .fw-md3-trailing-btn) .fw-md3-control {
    padding-right: 3rem !important;
}

/* A caller-supplied placeholder must not fight the resting label for the
   same spot: per MD3 it only shows once the label has floated (focus). The
   single-space float-driver placeholder is unaffected — it has no glyphs. */
.fw-md3-control:not(:focus)::placeholder {
    color: transparent;
}

.fw-md3-control:focus::placeholder {
    color: rgb(var(--md-sys-color-on-surface-variant));
}

/* Split phone field: the country prefix and the national number are separate
   controls, each in its own outline, sharing the row evenly. Below the
   breakpoint an even half would clip the country name, so the pair stacks
   instead. Containment sits on .fw-field, not the row: a container query
   cannot size an element against a context that element establishes. */
.fw-field:has(.fw-phone-row) {
    container-type: inline-size;
}

.fw-phone-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    /* The same rhythm the surrounding stack uses between fields, so the pair
       reads as two fields on one line rather than one split control. */
    gap: 1.5rem;
}

@container (min-width: 380px) {
    .fw-phone-row {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }
}

@supports not (container-type: inline-size) {
    @media (min-width: 380px) {
        .fw-phone-row {
            grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        }
    }
}

/* Multiline variant: the container grows with the textarea and the resting
   label pins to the first text line instead of the vertical center. */
.fw-md3-outlined--textarea {
    height: auto;
    min-height: 56px;
}

textarea.fw-md3-control {
    padding: 1rem !important;
    resize: vertical;
    line-height: 1.5rem;
    min-height: 56px;
}

.fw-md3-outlined--textarea .fw-md3-label {
    top: 1.75rem;
}

.fw-md3-control:focus ~ .fw-md3-label,
.fw-md3-control:not(:placeholder-shown) ~ .fw-md3-label {
    /* Repeated after the --textarea override so floating wins there too. */
    top: 0;
}

/* Interactive trailing slot (password visibility, date/time pickers):
   24dp icon centered in a 40dp round target, 4dp from the field edge so the
   icon itself sits at the spec's 12dp inset. */
.fw-md3-trailing-btn {
    position: absolute;
    right: 0.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: rgb(var(--md-sys-color-on-surface-variant));
    cursor: pointer;
    transition: background-color 150ms var(--md-sys-motion-easing-standard);
}

.fw-md3-trailing-btn:hover {
    background-color: rgb(var(--md-sys-color-on-surface) / 0.08);
}

.fw-md3-trailing-btn:focus-visible {
    outline: 2px solid rgb(var(--md-sys-color-primary));
    outline-offset: 1px;
}

.fw-md3-trailing-btn svg {
    width: 1.5rem;
    height: 1.5rem;
    display: block;
}

/* Native pickers get our trailing button instead of the browser's inline
   indicator. Unscoped from :has() and !important-ed: Wagtail admin ships its
   own date-input chrome, which otherwise leaves two calendar icons side by
   side. background-image is re-asserted for the same reason — some admin
   skins paint an icon onto the input itself. */
.fw-md3 input.fw-md3-control::-webkit-calendar-picker-indicator {
    display: none !important;
    -webkit-appearance: none !important;
    opacity: 0 !important;
    width: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
}

.fw-md3 input.fw-md3-control,
.fw-md3 select.fw-md3-control {
    background-image: none !important;
}

/* Firefox exposes no pseudo-element for its native date-picker icon, which
   it paints just inside the input's right padding edge. Shrink the right
   padding so the icon lands entirely within the trailing-button strip, then
   clip that strip away — our trailing button is a sibling, so it is not
   clipped and remains the single visible calendar icon. Scoped to Firefox
   via @supports; in Chromium the indicator is hidden by the rule above. */
@supports (-moz-appearance: none) {
    .fw-md3-outlined:has(.fw-md3-trailing-btn) input.fw-md3-control {
        padding-right: 0.5rem !important;
        clip-path: inset(0 2.75rem 0 0);
    }
}

/* Group label for checkbox/radio groups: styled like a floated field label,
   since these controls have no container to notch it into. */
.fw-md3-group-label {
    display: block;
    margin-bottom: 0.5rem;
    font-size: 0.75rem;
    line-height: 1rem;
    color: rgb(var(--md-sys-color-on-surface-variant));
}

.fw-md3--error .fw-md3-group-label {
    color: rgb(var(--md-sys-color-error));
}

/* ── MD3 anatomy for the search-family widgets ──
   (single_select_search, choice_dropdown). The pill trigger becomes the
   outlined field's control; label/outline live outside the HTMX swap target,
   so float state is driven by :has() — a hidden input exists only while
   something is selected, and aria-expanded flags an open panel. */

/* The outlined wrapper is a flex row; without explicit sizes the swap
   container shrinks to its content (an empty trigger label), leaving only a
   small clickable square — force the control chain to fill the field. */
.fw-sss-outlined .fw-widget-container,
.fw-sss-outlined .fw-sss-input {
    height: 100%;
    width: 100%;
    min-width: 0;
}

.fw-sss-trigger.fw-md3-control {
    display: flex !important;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    text-align: left;
    /* Rich item templates can render multi-line content taller than the
       56px field — clip instead of spilling over the outline. */
    overflow: hidden;
}

/* Optional trigger placeholder: hidden while closed (the resting label
   occupies that spot), revealed while the panel is open — MD3 placeholder
   semantics. */
.fw-sss-placeholder {
    opacity: 0;
    color: rgb(var(--md-sys-color-on-surface-variant));
    transition: opacity 150ms var(--md-sys-motion-easing-standard);
}

.fw-sss-outlined:has(.fw-sss-trigger[aria-expanded="true"]) .fw-sss-placeholder {
    opacity: 1;
}

/* Float the label / open the notch when: always-floated variant (choice
   dropdown), something is selected (hidden input present), or panel open. */
.fw-md3-outlined--floated .fw-md3-label,
.fw-sss-outlined:has(input[type="hidden"]) .fw-md3-label,
.fw-sss-outlined:has(.fw-sss-trigger[aria-expanded="true"]) .fw-md3-label {
    top: 0;
    font-size: 0.75rem;
}

.fw-md3-outlined--floated .fw-md3-notch,
.fw-sss-outlined:has(input[type="hidden"]) .fw-md3-notch,
.fw-sss-outlined:has(.fw-sss-trigger[aria-expanded="true"]) .fw-md3-notch {
    padding: 0 0.25rem;
    max-width: 100%;
}

/* Open/keyboard-focused trigger mirrors the control focus state. */
.fw-sss-outlined:has(.fw-sss-trigger[aria-expanded="true"]) .fw-md3-outline,
.fw-sss-outlined:has(.fw-sss-trigger:focus-visible) .fw-md3-outline {
    border-width: 2px;
    border-color: rgb(var(--md-sys-color-primary));
}

.fw-sss-outlined:has(.fw-sss-trigger[aria-expanded="true"]) .fw-md3-label {
    color: rgb(var(--md-sys-color-primary));
}

/* Error keeps the whole field in error color, beating the open-state primary
   (same specificity, later in the cascade). */
.fw-md3--error .fw-sss-outlined .fw-md3-outline {
    border-color: rgb(var(--md-sys-color-error));
}

.fw-md3--error .fw-sss-outlined .fw-md3-label {
    color: rgb(var(--md-sys-color-error));
}

.fw-md3-control option {
    background-color: rgb(var(--color-surface-50));
    color: rgb(var(--color-surface-900));
}

@media (prefers-color-scheme: dark) {
    .fw-md3-control option {
        background-color: rgb(var(--color-surface-800));
        color: rgb(var(--color-surface-100));
    }
}

/* Label rests inside the field (body-large, vertically centered) and floats
   into the outline notch (body-small) on focus or when populated. "Populated"
   is :not(:placeholder-shown): text/number controls carry a single-space
   placeholder for exactly this, and a <select> can never match
   :placeholder-shown, so its label is permanently floated — correct, since a
   native select always renders a selection. */
.fw-md3-label {
    position: absolute !important;
    top: 50%;
    left: 1rem !important;
    transform: translateY(-50%);
    display: block !important;
    margin: 0 !important;
    padding: 0 !important;
    font-size: 1rem;
    font-weight: 400 !important;
    line-height: 1 !important;
    color: rgb(var(--md-sys-color-on-surface-variant));
    pointer-events: none;
    cursor: default;
    transition: top 150ms var(--md-sys-motion-easing-standard),
                font-size 150ms var(--md-sys-motion-easing-standard),
                color 150ms var(--md-sys-motion-easing-standard);
}

.fw-md3-control:focus ~ .fw-md3-label,
.fw-md3-control:not(:placeholder-shown) ~ .fw-md3-label {
    top: 0;
    font-size: 0.75rem;
}

/* The outline itself. Top inset compensates for the legend's line box so the
   border-top aligns with the visual top of the field. */
.fw-md3-outline {
    position: absolute !important;
    inset: -0.375rem 0 0 0 !important;
    display: block !important;
    width: auto !important;
    min-width: 0 !important;
    margin: 0 !important;
    /* 12px + the notch's 4px side padding = legend text starts at 16px,
       exactly under the floated label. */
    padding: 0 0.75rem !important;
    border: 1px solid rgb(var(--md-sys-color-outline));
    border-radius: var(--md-sys-shape-corner-extra-small) !important;
    background: transparent !important;
    box-shadow: none !important;
    pointer-events: none;
    transition: border-color 200ms var(--md-sys-motion-easing-standard);
}

/* The border itself stays un-!important-ed (focus/error swap width/color),
   but everything that lets the legend cut its notch gap is armored:
   Wagtail's admin CSS floats legends inline at 16.67% width, which silently
   disables the fieldset notch. */
.fw-md3-notch,
fieldset.fw-md3-outline > legend.fw-md3-notch {
    float: none !important;
    display: block !important;
    position: static !important;
    width: auto !important;
    margin: 0 !important;
    border: 0 !important;
    height: auto !important;
    visibility: visible !important;
}

/* The notch is collapsed while the label rests inside the field and opens
   (4dp padding each side, per spec) when the label floats. */
.fw-md3-notch {
    padding: 0;
    max-width: 0;
    white-space: nowrap;
    font-size: 0.75rem;
    line-height: 0.75rem;
    max-height: 0.75rem;
    transition: max-width 150ms var(--md-sys-motion-easing-standard),
                padding 150ms var(--md-sys-motion-easing-standard);
}

.fw-md3-control:focus ~ .fw-md3-outline .fw-md3-notch,
.fw-md3-control:not(:placeholder-shown) ~ .fw-md3-outline .fw-md3-notch {
    padding: 0 0.25rem;
    max-width: 100%;
}

/* Invisible twin of the label text — only there to size the border gap. */
.fw-md3-notch > span {
    visibility: hidden;
}

/* Explicitly label-less fields must never open a gap in the top border —
   !important so the focus/populated notch-opening states can't override. */
.fw-md3-notch--empty {
    padding: 0 !important;
    max-width: 0 !important;
    width: 0 !important;
}

/* An empty legend has no line box, so the fieldset would draw its top border
   at the fieldset's own top edge — 6px above the field — instead of pushing
   it down through the legend's middle like labeled fields do. A zero-width
   space restores the line box without opening a notch. */
.fw-md3-notch--empty::before {
    content: "\200B";
}

.fw-md3-trailing {
    position: absolute;
    right: 0.75rem;
    width: 1.5rem;
    height: 1.5rem;
    color: rgb(var(--md-sys-color-on-surface-variant));
    pointer-events: none;
    transition: color 200ms var(--md-sys-motion-easing-standard);
}

/* States: hover darkens the outline, focus thickens it to 2px in primary —
   no glow/box-shadow halo, per MD3. */
.fw-md3-outlined:hover .fw-md3-outline {
    border-color: rgb(var(--md-sys-color-on-surface));
}

.fw-md3-control:focus ~ .fw-md3-outline {
    border-width: 2px;
    border-color: rgb(var(--md-sys-color-primary));
}

.fw-md3-control:focus ~ .fw-md3-label {
    color: rgb(var(--md-sys-color-primary));
}

/* Error state colors the whole field, not just the message. */
.fw-md3--error .fw-md3-outline,
.fw-md3--error .fw-md3-outlined:hover .fw-md3-outline,
.fw-md3--error .fw-md3-control:focus ~ .fw-md3-outline {
    border-color: rgb(var(--md-sys-color-error));
}

.fw-md3--error .fw-md3-label,
.fw-md3--error .fw-md3-control:focus ~ .fw-md3-label,
.fw-md3--error .fw-md3-supporting {
    color: rgb(var(--md-sys-color-error));
}

/* Disabled: MD3 uses on-surface at 38% for content, 12% for the outline. */
.fw-md3-control:disabled {
    color: rgb(var(--md-sys-color-on-surface) / 0.38);
    cursor: default;
}

.fw-md3-control:disabled ~ .fw-md3-outline {
    border-color: rgb(var(--md-sys-color-on-surface) / 0.12);
}

.fw-md3-control:disabled ~ .fw-md3-label,
.fw-md3-control:disabled ~ .fw-md3-trailing {
    color: rgb(var(--md-sys-color-on-surface) / 0.38);
}

/* Supporting text replaces the hover help tooltip; also hosts errors. */
.fw-md3-supporting {
    margin: 0.25rem 0 0 !important;
    padding: 0 1rem !important;
    font-size: 0.75rem !important;
    font-weight: 400 !important;
    line-height: 1rem !important;
    color: rgb(var(--md-sys-color-on-surface-variant));
}

.fw-md3-supporting span {
    display: block;
}

/* ── Dark Mode ── */

@media (prefers-color-scheme: dark) {
    /* Choice, toggle, and segmented widgets are dark-mode-aware through the
       .fw-md3 token block — no per-rule overrides needed here. */

    /* Search — dark mode tokens are handled by .fw-sss-input media query above */

    /* Multi Select Chips and Segmented Control — dark mode handled by the
       .fw-md3 token block. */
}
