/* 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));
}

/* 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. */
}
