/* ============================================================================
   FIELDSETS.CSS - Form Field Styling
   ============================================================================
   
   Styles for the FieldsetBuilder form system.
   
   ============================================================================ */


/* ============================================================================
   BASE / GENERIC FIELDSET STYLES
   ============================================================================ */

/* Container */
.fieldset-container {
    width: 100%;
    display: flex;
    flex-direction: column;
}

.fieldset-header {
    font-size: 14px;
    font-weight: bold;
    color: var(--blue-500);
    margin-bottom: 16px;
    padding-bottom: 8px;
    border-bottom: 1px solid #333;
}

.fieldset {
    width: 100%;
    margin-bottom: 10px;
}

.fieldset-divider {
    width: 100%;
    height: 1px;
    background: #333;
    margin: 8px 0;
}

/* Label */
.fieldset-label {
    display: flex;
    align-items: center;
    /* 10px label-to-element gap form-wide (operator law 2026-09-08,
       approved after trial; was 6px). */
    margin-bottom: 10px;
    position: relative;
}

.fieldset-label-text {
    font-size: 13px;
    color: #fff;
}

/* THE UMBRELLA RULE (operator 2026-09-22): a fieldset holding sublabels OR a
   Modify carrier seated inside it (formbuilder.js formbuilderSeatEmbeddedCarrier:
   ticket-url in Sessions, item-url in Item Pricing, youtube-url in Images,
   public-phone / public-email in Links) is an umbrella — its headline outranks
   its children, and its dot sums theirs (completeness.js). One rule, no
   per-screen styling: a new fieldset or a new modifier gets the look by itself.
   THIRD CONDITION (operator 2026-09-22, "it has children"): a fieldset whose
   content holds another completeness dot — a child's, never its own headline's
   — is an umbrella too: Timelines (its timeline bars wear dots) with no
   sublabel and no modifier. Single-field fieldsets carry only their headline's
   dot and stay 13px.
   A fieldset with named parts (it contains sublabels) is a parent — its
   headline outranks the 13px sublabels. Single-field fieldsets (Title,
   Description, Images) never contain sublabels and keep the base size.
   Self-applying: future fieldsets inherit the correct treatment by simply
   having or not having sublabels (operator 2026-08-21). Sublabels inside a
   time picker modal are excluded — the popup opening must never resize the
   fieldset headline (2026-08-25). */
/* Both headline shapes: the bare label, and the label inside the wrapper that
   buildLabel makes when the fieldset has an instruction (Links) - the wrapper
   hid the headline from this rule until 2026-09-22. */
.fieldset:has(.fieldset-sublabel:not(.fieldset-sessions-timepickermodal *), .fieldset[data-sessionsfields-embedded="true"], .fieldset[data-itempricingfields-embedded="true"], .fieldset[data-mediafields-embedded="true"], .fieldset[data-contactdetails-embedded="true"], > :not(.fieldset-label, .fieldset-label-wrapper) .fieldset-label-required:not(.fieldset-sessions-timepickermodal *)) > .fieldset-label .fieldset-label-text,
.fieldset:has(.fieldset-sublabel:not(.fieldset-sessions-timepickermodal *), .fieldset[data-sessionsfields-embedded="true"], .fieldset[data-itempricingfields-embedded="true"], .fieldset[data-mediafields-embedded="true"], .fieldset[data-contactdetails-embedded="true"], > :not(.fieldset-label, .fieldset-label-wrapper) .fieldset-label-required:not(.fieldset-sessions-timepickermodal *)) > .fieldset-label-wrapper > .fieldset-label .fieldset-label-text {
    font-size: 15px;
    font-weight: 600;
}

/* The completeness dot (.fieldset-label-required / --complete) lives in
   components/completeness.css (2026-09-16). */

/* Label wrapper (contains label + instruction when instruction exists) */
.fieldset-label-wrapper {
    display: block;
}

/* Instruction Text (generic, for all fieldsets). Rendered with textContent —
   pre-line makes plain line breaks in the stored text lay out as paragraphs,
   so instruction copy never needs HTML. */
.fieldset-instruction {
    font-size: 13px;
    color: #aaa;
    line-height: 1.5;
    white-space: pre-line;
}

/* The info circle and its tooltip box live in components/tooltip.css (operator 2026-09-17). */

/* LOCKED LOCATION (operator 2026-09-17): the padlock beside the place
   fieldset's dot (site icon icon_locked, 14px like the info circle; #888
   reads on both themes), and the expired grey (#808080 both themes, the
   post-session-option--expired grey) on the disabled place and its
   receipt. Stamped by member/posteditor.js posteditorLockLocationContainer. */
.fieldset-label-locked {
    width: 14px;
    height: 14px;
    margin-left: 6px;
    flex-shrink: 0;
    cursor: pointer;
    background-color: #888;
    -webkit-mask-image: var(--ui-icon-locked);
    mask-image: var(--ui-icon-locked);
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
}

.fieldset--locked .fieldset-input:disabled,
.fieldset--locked .fieldset-venue-address-display,
.fieldset--locked .fieldset-location-status.success,
.fieldset--locked .fieldset-sublabel:has(.fieldset-label-locked),
.fieldset--locked .fieldset-sublabel:has(.fieldset-label-locked) .fieldset-label-required--complete {
    color: #808080;
}

.fieldset--locked .fieldset-venue-address-display,
.fieldset--locked .fieldset-input:disabled {
    pointer-events: none; /* the click lands on the input wrap, the tooltip's trigger */
}

.fieldset--locked .fieldset-location-inputwrap {
    cursor: pointer; /* a click here opens the locked tooltip, like the padlock */
}

.fieldset-sublabel {
    display: flex;
    align-items: center;
    font-size: 13px;
    color: #fff;
    /* 10px sublabel-to-element gap form-wide (operator 2026-09-08,
       duplicating the Location Type / toggle spacing; bottom margins
       only — top margins are banned). */
    margin-bottom: 10px;
}

/* Input - layout only, appearance from input-class-1 in base.css */
.fieldset-input {
    width: 100%;
    height: 36px;
    padding: 0 10px;
    font-size: 13px;
    box-sizing: border-box;
}

.fieldset-input[type="number"] {
    -moz-appearance: textfield;
    appearance: textfield;
}

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

/* Browser autofill styling uses global rule from base.css */
/* Animation name: global-autofill-detected */

/* INVALID = red border ONLY WHILE FOCUSED (operator 2026-09-06): at rest a
   problem is carried by the red label dot alone — no resting flamethrower.
   The --invalid class itself stays on the element (the dot pairing and the
   Post Studio census read it); only the paint is focus-scoped. */
.fieldset-input--invalid:focus {
    border-color: var(--red-600);
}

/* Char Count */
.fieldset-char-count {
    font-size: 11px;
    color: #666;
    text-align: right;
    margin-top: 3px;
}

.fieldset-char-count--warning {
    color: #f59e0b;
}

.fieldset-char-count--danger {
    color: #ef4444;
}

/* Textarea */
/* Textarea - layout only, appearance from input-class-1 in base.css */
.fieldset-textarea {
    width: 100%;
    min-height: 120px;
    padding: 10px;
    font-size: 13px;
    resize: none;
}

/* Invalid state — when the textarea inside the wrapper is marked invalid,
   the wrapper turns red as one continuous shape, ONLY WHILE FOCUSED
   (operator 2026-09-06 — same focus-scoping as the input rule above). */
.component-textarearesize:focus-within:has(.fieldset-textarea.fieldset-input--invalid) {
    border-color: var(--red-600);
}

/* ----------------------------------------------------------------------------
   FIELDSET MENU
   Uses menu-class-1 for appearance; this section is LAYOUT ONLY.
   ---------------------------------------------------------------------------- */

.fieldset-menu {
    width: 100%;
    height: 36px;
    position: relative;
}

.fieldset-menu-button {
    width: 100%;
    height: 36px;
    display: flex;
    align-items: center;
    padding: 0 10px;
    cursor: pointer;
}

.fieldset-menu-button-image {
    width: 24px;
    height: 24px;
    object-fit: contain;
    flex-shrink: 0;
}

.fieldset-menu-button-text {
    flex: 1;
    text-align: left;
    padding-left: 10px;
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fieldset-menu-button-input {
    flex: 1;
    text-align: left;
    padding-left: 10px;
    font-size: 13px;
    min-width: 0;
}

.fieldset-menu:not(.fieldset-menu--open) .fieldset-menu-button-input {
    pointer-events: none;
}

.fieldset-menu-button-arrow {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.fieldset-menu-options {
    display: none;
    position: absolute;
    top: 36px;
    left: 0;
    width: 100%;
    max-height: 300px;
    overflow-y: auto;
    z-index: var(--layer-menu, 85);
}

.fieldset-menu-options--open {
    display: block;
}

.fieldset-menu-option {
    width: 100%;
    height: 36px;
    display: flex;
    align-items: center;
    padding: 0 10px;
    cursor: pointer;
}

.fieldset-menu-option-image {
    width: 24px;
    height: 24px;
    object-fit: contain;
    flex-shrink: 0;
}

.fieldset-menu-option-text {
    flex: 1;
    text-align: left;
    padding-left: 10px;
    font-size: 13px;
}

/* Select */
.fieldset-select {
    width: 100%;
    height: 36px;
    padding: 0 10px;
    background: #222;
    border: 1px solid #333;
    border-radius: 8px;
    color: #fff;
    font-size: 13px;
    cursor: pointer;
    appearance: none;
}

.fieldset-select option {
    background: #222;
    color: #fff;
}

.fieldset-select option:checked,
.fieldset-select option:focus {
    background: var(--blue-600);
    color: #fff;
}

.fieldset-select:hover {
    border-color: #555;
}

.fieldset-select:focus {
    outline: none;
    border-color: var(--blue-500);
}

/* ============================================================================
   CUSTOM DROPDOWN FIELDSET (MenuManager dropdown with animated ▼ arrow)
   Appearance governed by menu-class-1 from base.css.
   This section contains LAYOUT ONLY.
   ============================================================================ */

.fieldset-customdropdown {
    width: 100%;
    height: 36px;
    position: relative;
}

.fieldset-customdropdown-button {
    width: 100%;
    height: 36px;
    display: flex;
    align-items: center;
    padding: 0 10px;
}

.fieldset-customdropdown-button-text {
    flex: 1;
    text-align: left;
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fieldset-customdropdown-button-arrow {
    width: 20px;
    height: 20px;
    margin-left: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
}

.fieldset-customdropdown-options {
    position: absolute;
    top: 36px;
    left: 0;
    width: 100%;
    box-sizing: border-box;
    z-index: var(--layer-menu, 85);
}

/* Drawer animation: height/overflow on outer via base.css :has() rule.
   max-height + scrolling live on the inner wrapper. */
.fieldset-customdropdown-options > .menu-options-inner {
    max-height: 300px;
    overflow-y: auto;
    overflow-x: hidden;
}

.fieldset-customdropdown-option {
    width: 100%;
    height: 36px;
    display: flex;
    align-items: center;
    padding: 0 10px;
    font-size: 13px;
}

/* ============================================================================
   CUSTOM CHECKLIST FIELDSET
   - Always-visible checklist (multi-select)
   - 36px rows, no vertical gaps between rows (amenities-style)
   ============================================================================ */

.fieldset-customchecklist {
    width: 100%;
    display: flex;
    flex-direction: column;
    border: none;
    border-radius: 0;
    overflow: visible;
    background: transparent;
}

.fieldset-customchecklist-row {
    width: 100%;
    height: 36px;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 10px;
    box-sizing: border-box;
    background: transparent;
    border: none;
    color: #fff;
    cursor: pointer;
    font: inherit;
}

.fieldset-customchecklist-row:first-child { border-radius: 0; }
.fieldset-customchecklist-row:last-child { border-radius: 0; }

.fieldset-customchecklist-row-box {
    width: 20px;
    height: 20px;
    position: relative;
    flex: 0 0 20px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fieldset-customchecklist-row-boximg {
    width: 20px;
    height: 20px;
    display: block;
    object-fit: contain;
    position: relative;
    z-index: 2;
    /* Default: checkbox looks "disabled"/unselected (gray on dark UI) */
    filter: brightness(0) invert(0.45);
    opacity: 0.9;
}

.fieldset-customchecklist-row--selected .fieldset-customchecklist-row-boximg {
    /* Selected: checkbox becomes white */
    filter: brightness(0) invert(1);
    opacity: 1;
}

.fieldset-customchecklist-row-check {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 18px;
    height: 18px;
    transform: translate(-50%, -50%);
    display: block;
    object-fit: contain;
    z-index: 1;
}

.fieldset-customchecklist-row-text {
    flex: 1;
    text-align: left;
    font-size: 13px;
    color: #fff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Radio */
.fieldset-radio-group {
    display: flex;
    flex-direction: column;
    gap: 0;
    border: none;
    border-radius: 0;
    overflow: visible;
    background: transparent;
}

.fieldset-radio {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 12px;
    cursor: pointer;
    height: 36px;
    padding: 0 10px;
    box-sizing: border-box;
    background: transparent;
    border: none;
    margin: 0;
    color: #fff;
    font: inherit;
    text-align: left;
}

.fieldset-radio:first-child { border-radius: 0; }
.fieldset-radio:last-child { border-radius: 0; }

.fieldset-radio-box {
    width: 20px;
    height: 20px;
    position: relative;
    flex: 0 0 20px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fieldset-radio-icon {
    width: 20px;
    height: 20px;
    display: block;
    object-fit: contain;
}

.fieldset-radio-icon-selected {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 14px;
    height: 14px;
    transform: translate(-50%, -50%);
    display: block;
    object-fit: contain;
}

.fieldset-radio-text {
    flex: 1;
    text-align: left;
    font-size: 13px;
    color: #fff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Row */
.fieldset-row {
    display: flex;
    gap: 10px;
    align-items: flex-end;
}

.fieldset-row .fieldset-input {
    margin-bottom: 0;
}

.fieldset-row-item {
    flex: 1;
}

.fieldset-row-item--menu {
    flex: 0 0 120px;
}

.fieldset-row-item--currency-wrapper {
    flex: 0 0 120px;
}

.fieldset-row-item--currency-compact {
    flex: 0 0 100px;
}

.fieldset-row-item--input-small {
    flex: 0 0 100px;
}

.fieldset-row-item--no-flex {
    flex: 0 0 auto;
}

/* Date and Time */
.fieldset-date,
.fieldset-time {
    width: 100%;
    height: 36px;
    padding: 0 10px;
    /* Must sit directly on panel (same as amenities/radio): no background fill */
    background: transparent;
    /* Must sit directly on panel (same as amenities): no background fill */
    background: transparent;
    border: 1px solid #333;
    border-radius: 8px;
    color: #fff;
    font-size: 13px;
    caret-color: #fff;
}

.fieldset-date::-webkit-calendar-picker-indicator,
.fieldset-time::-webkit-calendar-picker-indicator {
    filter: invert(1);
    cursor: pointer;
}

.fieldset-date:hover,
.fieldset-time:hover {
    border-color: #555;
}

.fieldset-date:focus,
.fieldset-time:focus {
    outline: none;
    border-color: var(--blue-500);
}

/* Compact Currency/Phone Prefix */
.fieldset-currency-compact {
    width: 120px;
    height: 36px;
    position: relative;
    flex-shrink: 0;
}

.fieldset-menu-button--compact {
    width: 120px;
}

.fieldset-menu-button-input--compact {
    padding-left: 6px;
    font-size: 12px;
}

.fieldset-menu-options--compact {
    width: 250px;
    left: 0;
    right: auto;
    border-top: 1px solid var(--blue-500);
    border-radius: 8px;
    z-index: var(--layer-menu, 85);
}


/* ============================================================================
   IMAGES FIELDSET
   ============================================================================ */

.fieldset-images-container {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 5px;
    width: 100%;
}

/* RESTORING (operator 2026-09-10): the stored picks are on their way - the
   site's ONE ring (base.css declaration list), centred in a tile-high box;
   the mid-grey triple reads on both themes (poststudio.css cell ring). */
.fieldset-images-container--restoring {
    position: relative;
    height: 80px;
}

.fieldset-images-container--restoring::after {
    --loadingring-size: 16px;
    --loadingring-color: 136,136,136;
    top: 50%;
    left: 50%;
    margin: -8px 0 0 -8px;
}

.fieldset-images-item {
    position: relative;
    aspect-ratio: 1;
    border-radius: 8px;
    overflow: hidden;
    background: #222;
    border: 1px solid #333;
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
}

/* Tile loading ring (operator 2026-09-12): the site's one ring, centred in
   the box until its CDN thumbnail lands — the --restoring ring above, on the
   tile's own dark ground (the ring's size/colour twin at ~672). */
.fieldset-images-item--loading::after {
    --loadingring-size: 16px;
    --loadingring-color: 136,136,136;
    top: 50%;
    left: 50%;
    margin: -8px 0 0 -8px;
}

.fieldset-images-item.fieldset-images-item--dragging {
    opacity: 1;
}

.fieldset-images-item.fieldset-images-item--dragready {
    outline: 2px solid rgba(59, 130, 246, 0.85);
    outline-offset: -2px;
    cursor: grab;
    user-select: none;
}

.fieldset-images-item.fieldset-images-item--dragready:active {
    cursor: grabbing;
}

.fieldset-images-item-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* YouTube tile watermark — a centered play triangle drawn purely from CSS borders
   so it stays sharp at any size and needs no admin-uploaded asset. The tile already
   has position:relative + overflow:hidden, so the absolutely-positioned ::before
   sits on top of the still thumbnail. translateX(2px) optical-centers the triangle
   (its visual mass leans left). The 6×6 hit-area on remove buttons and clicks on
   the tile itself are unaffected because pointer-events:none. */
.fieldset-images-item--youtube::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 14px 0 14px 22px;
    border-color: transparent transparent transparent rgba(255, 255, 255, 0.95);
    transform: translate(-50%, -50%) translateX(2px);
    filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
    pointer-events: none;
    z-index: 1;
}

.fieldset-images-item-button-remove {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 20px;
    height: 20px;
    background: rgba(0, 0, 0, 0.7);
    border: none;
    border-radius: 50%;
    color: #fff;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fieldset-images-item-button-icon {
    width: 18px;
    height: 18px;
    object-fit: contain;
    flex-shrink: 0;
}

.fieldset-images-item-button-remove:hover {
    background: rgba(239, 68, 68, 0.9);
}

/* LOADING RING (operator 2026-09-11): while picked files are being
   shrunk, validated and stored, the Add Image tile wears the site's one
   loading ring in its top-right corner (the base.css ring rule; this
   selector is listed there). */
.fieldset-images-button-add--loading {
    position: relative;
}
.fieldset-images-button-add--loading::after {
    top: 6px;
    right: 6px;
}
.fieldset-images-button-add {
    aspect-ratio: 1;
    padding: 0;
    background: #222;
    border: 1px solid #333;
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    cursor: pointer;
    color: rgba(255,255,255,0.9);
}

.fieldset-images-button-add-icon {
    width: 28px;
    height: 28px;
    display: block;
    background-color: currentColor;
    -webkit-mask-image: var(--ui-icon-add-image);
    mask-image: var(--ui-icon-add-image);
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
}

.fieldset-images-button-add-text {
    font-size: 13px;
    font-weight: 600;
    color: inherit;
}

.fieldset-images:hover {
    border-color: var(--blue-500);
}

/* Images Basket - shows all post_media as mini-thumbs */
.fieldset-images-basket-label {
    margin-top: 10px;
    margin-bottom: 10px;
    font-size: 13px;
    font-weight: 500;
    /* Theme token, not hardcoded white — the label was invisible in light
       theme (operator repro 2026-09-08; --text-secondary IS 0.6 white on
       the dark base, so dark is unchanged). */
    color: var(--text-secondary);
}

.fieldset-images-basket {
    display: flex;
    flex-wrap: nowrap;
    gap: 5px;
    padding-bottom: 5px;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
}

.fieldset-images-basket-item {
    width: 50px;
    height: 50px;
    min-width: 50px;
    border-radius: 4px;
    overflow: hidden;
    background: #222;
    opacity: 0.5;
    transition: opacity 0.15s ease, border-color 0.15s ease;
    border: 2px solid transparent;
    flex-shrink: 0;
}

.fieldset-images-basket-item:hover {
    opacity: 0.8;
}

.fieldset-images-basket-item--active {
    opacity: 1;
    border-color: #3b82f6;
    cursor: default;
}

.fieldset-images-basket-item-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Play-triangle watermark for YouTube history tiles. Same primitive as the
   main Images list, scaled smaller to fit the 50×50 thumb. The .basket-item
   container already has position relative implicitly via the outer flex
   layout — explicit position:relative is added below to anchor the ::before. */
.fieldset-images-basket-item--youtube {
    position: relative;
}

.fieldset-images-basket-item--youtube::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 7px 0 7px 11px;
    border-color: transparent transparent transparent rgba(255, 255, 255, 0.95);
    transform: translate(-50%, -50%) translateX(1px);
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6));
    pointer-events: none;
    z-index: 1;
}


/* ============================================================================
   AMENITIES FIELDSET
   ============================================================================ */

.fieldset-amenities-container {
    display: block;
}

/* NONE tile — built into every amenities grid but shown ONLY inside the
   Locations Modal sideways strip (postmanager.css skin); hidden in the
   classic Yes/No list. */
.fieldset-amenities-none {
    display: none;
}

.fieldset-amenities-row {
    display: grid;
    grid-template-columns: 24px 1fr auto;
    align-items: center;
    column-gap: 12px;
    height: 36px;
}

.fieldset-amenities-row:last-child {
    margin-bottom: 0;
}

.fieldset-amenities-row-image {
    width: 24px;
    height: 24px;
    object-fit: contain;
    filter: brightness(0) invert(1);
}

.fieldset-amenities-row-image--yes {
    filter: brightness(0) saturate(100%) invert(45%) sepia(95%) saturate(1000%) hue-rotate(200deg) brightness(100%);
}

.fieldset-amenities-row-image--no {
    filter: brightness(0) invert(0.4);
}

.fieldset-amenities-row-text {
    font-size: 13px;
    color: #fff;
}

.fieldset-amenities-row-text--no {
    color: #666;
}

.fieldset-amenities-row-options {
    display: grid;
    grid-auto-flow: column;
    column-gap: 16px;
    height: 100%;
    align-self: stretch;
}

.fieldset-amenities-option {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 13px;
    color: #ccc;
    padding: 0;
    border: none;
    background: transparent;
    transition: color 0.15s;
    height: 100%;
}

.fieldset-amenities-option:hover {
    color: #fff;
}

.fieldset-amenities-option-icon {
    width: 20px;
    height: 20px;
    position: relative;
    flex: 0 0 20px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fieldset-amenities-option-radio {
    width: 20px;
    height: 20px;
    display: block;
    object-fit: contain;
}

.fieldset-amenities-option-radio-selected {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 14px;
    height: 14px;
    transform: translate(-50%, -50%);
    display: block;
    object-fit: contain;
}

.fieldset-amenities-option-text {
    font-size: 13px;
    color: inherit;
}



/* ============================================================================
   AGE RATING FIELDSET
   ============================================================================ */

.fieldset-agerating-menu {
    width: 100%;
}


/* ============================================================================
   ITEM PRICING FIELDSET
   ============================================================================ */

.fieldset-itempricing-sublabel-itemname,
.fieldset-itempricing-sublabel-currency,
.fieldset-itempricing-sublabel-itemprice,
.fieldset-itempricing-sublabel-itemvariants {
    font-size: 13px;
    color: #fff;
    margin-bottom: 6px;
}


.fieldset-itempricing-input-itemname,
.fieldset-itempricing-input-itemprice,
.fieldset-itempricing-input-itemvariantname {
    width: 100%;
    height: 36px;
    padding: 0 10px;
}

.fieldset-itempricing-input-itemname {
    margin-bottom: 10px;
}

.fieldset-itempricing-row-itemprice {
    display: flex;
    gap: 10px;
    align-items: flex-end;
    margin-bottom: 10px;
}

.fieldset-itempricing-row-itemvariant {
    display: flex;
    gap: 10px;
    align-items: center;
    margin-bottom: 10px;
}

.fieldset-itempricing-container-itemvariants {
    display: flex;
    flex-direction: column;
}


.fieldset-itempricing-row-variantimage {
    display: flex;
    flex-wrap: nowrap;
    gap: 5px;
    overflow-x: auto;
    min-height: 50px;
    /* 3px clears the selected tile's 2px glow ring (top); the larger bottom value
       adds breathing room between the tiles and the horizontal scrollbar. No side
       padding — the tiles use the full row width. */
    padding: 3px 0 8px;
}

/* Border/selection treatment mirrors .component-avatarpicker-tile (components.css) —
   the shared look for all thumbnail pickers. Light values in themes.css. */
.fieldset-itempricing-variantimage-item {
    width: 50px;
    height: 50px;
    min-width: 50px;
    border-radius: 4px;
    overflow: hidden;
    border: 2px solid rgba(255,255,255,0.12);
    box-sizing: border-box;
}

.fieldset-itempricing-variantimage-item:hover {
    opacity: 0.8;
}

.fieldset-itempricing-variantimage-item--selected {
    border-color: var(--btn-selected, #3b82f5);
    box-shadow: 0 0 0 2px rgba(59,130,246,0.25);
}

.fieldset-itempricing-variantimage-item--empty {
    cursor: default;
}

.fieldset-itempricing-variantimage-item--empty:hover {
    opacity: 1;
}

.fieldset-itempricing-variantimage-item-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Site promo prefix — joins the left of the promo code input. Colour/border are
   theme-aware (light values in themes.css). */
.fieldset-itempricing-promo-sitepromo-prefix,
.fieldset-ticketpricing-promo-sitepromo-prefix {
    color: #fff;
    border: 1px solid #444;
    border-right: none;
}

/* ============================================================================
   LINKS FIELDSET
   ============================================================================ */

.fieldset-links-rows {
    display: flex;
    flex-direction: column;
}

/* ONE ROW PER LINK (operator 2026-09-11): icon-only picker, URL, apply,
   minus. (flex predates the 2026-08-29 ruling; the row is the existing
   .fieldset-row idiom.) */
.fieldset-links-row {
    display: flex;
    gap: 10px;
    align-items: center;
    margin-bottom: 10px;
}

/* The picker shows its icon only - the name rides the button's tooltip -
   the width of a phone prefix menu. The options list keeps its names and
   opens wider than its button. */
.fieldset-links-type-menu.fieldset-row-item {
    flex: 0 0 64px;
    min-width: 0;
}
.fieldset-links-type-menu .component-linkpicker-menu-button-text {
    display: none;
}
.fieldset-links-type-menu .component-linkpicker-menu-button-image {
    margin-right: 6px;
}
.fieldset-links-type-menu .component-linkpicker-menu-options {
    width: 240px;
}

.fieldset-links-url {
    width: 100%;
    min-width: 0;
}

/* Summary rows carrying the block-level Ricochet (operator 2026-09-11):
   the summary fills the row, 10px, the bare 36px button. */
.fieldset-links-summary-actions,
.fieldset-amenities-gridrow,
.fieldset-url-row {
    display: flex;
    gap: 10px;
    align-items: flex-start;
}
.fieldset-links-summary-actions .fieldset-links-summary-row,
.fieldset-amenities-gridrow > :first-child,
.fieldset-url-row .fieldset-input {
    flex: 1;
    min-width: 0;
}
/* The amenities tile strip is shorter than the 36px button: centre the
   pair so the tiles and the button share one midline. */
.fieldset-amenities-gridrow {
    align-items: center;
}
/* A multi-row summary (timelines) carries its Ricochet on the LABEL row.
   The button is pinned OUT OF FLOW (the .fieldset-timelines-index-drag
   pattern, ~2979) so it can never set the row's height: the label stays
   text-height and its gap down to the first summary button is the same
   10px as every other label on the form (operator 2026-09-19 - the 36px
   bar this row used to wear made that gap ~19px, and kept it wrong even
   when the Ricochet was hidden). */
.fieldset-label--ricochet {
    padding-right: 36px;
}
.fieldset-label--ricochet .component-ricochet-button {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    height: auto;
}
/* Ticket group header Ricochet: bare like the X beside it, in the header's
   white. (The timelines twin went with the timelines groups, 2026-09-19.) */
.fieldset-ticketpricing-ticketgroup-ricochet.button-class-7 {
    border-color: transparent;
    color: #fff;
    margin-left: 4px;
}
/* Ticket group editor rows: control + Ricochet (the row grammar). */
.fieldset-ticketpricing-ricochet-row {
    display: flex;
    gap: 10px;
    align-items: center;
    margin-bottom: 10px;
}
.fieldset-ticketpricing-ricochet-row > :first-child {
    flex: 1;
    min-width: 0;
}
.fieldset-ticketpricing-promo-option-toggle,
.fieldset-ticketpricing-allocated-toggle {
    grid-template-columns: repeat(var(--toggle-count, 2), 1fr);
}

/* The row's X - .clear-button (components.css ~59) in the filter keyword
   clear's own box (filter.css ~488: 36px, 8px radius, the faint border and
   fill, grey idle); light twin in themes.css. */
.fieldset-links-remove.clear-button {
    flex: 0 0 36px;
    border-radius: 8px;
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.1);
    color: rgba(255, 255, 255, 0.5);
}
.fieldset-links-remove.clear-button:hover:not(:disabled) {
    opacity: 1;
    color: #fff;
}
.fieldset-links-remove.clear-button:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

/* "+ Add Link" / "+ Add Group" (timelines, ticket pricing) - the Form
   Builder's add subcategory button (formbuilder.css ~593); light twins in
   themes.css. The group headers' one control is the bare X (.clear-button)
   in the header's white. */
.fieldset-timelines-timeline-remove.clear-button,
.fieldset-ticketpricing-ticketgroup-remove.clear-button {
    color: #fff;
    margin-left: 4px;
}
/* Appearance from button-class-14 (base.css); these carry layout only. */
.fieldset-links-add,
.fieldset-timelines-add-timeline,
.fieldset-ticketpricing-add-group {
    width: 100%;
    margin-bottom: 10px;
}

/* ============================================================================
   LOCATION FIELDSET
   ============================================================================ */

.fieldset-location-status {
    font-size: 11px;
    color: #888;
    /* No margin above — margins live underneath things (operator 2026-08-24). */
    margin: 0;
}

.fieldset-location-actionsrow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    /* No margin above — same rule as the status line (operator 2026-08-24). */
    margin: 0;
}

.fieldset-location-actionsrow .fieldset-location-status {
    margin-top: 0;
    flex: 1 1 auto;
    min-width: 0;
}

.fieldset-location-actionsright {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: flex-end;
}

.fieldset-location-status.success {
    color: #22c55e;
}

.fieldset-location-status.error {
    color: #ef4444;
}

/* Google Places script still loading — the site's ONE loading ring
   (base.css) at status-row scale. Ring colours ride the
   status row's own #888 so it reads on both themes. */
.fieldset-location-status.waiting {
    position: relative;
    min-height: 15px;
}

/* Ring declared once in base.css; only the grey and the leading position
   differ here (the default 13px size is already correct). */
.fieldset-location-status.waiting::after {
    --loadingring-color: 136,136,136;
    left: 0;
    top: 50%;
    margin-top: -6.5px;
}

.fieldset-location-inputwrap {
    position: relative;
    width: 100%;
    /* ONE location layout, margins underneath only (operator 2026-08-24):
       10px under the input (10-12-6 rule), for city, venue, and address
       alike — was a venue-only inline style. */
    margin-bottom: 10px;
}

/* Locations mode toggle — toggle-class-1 wearer (operator 2026-09-06).
   Every wearer supplies its own grid columns (admin.css ~814); this one's
   count varies per subcategory (2 or 3 allowed modes), so it reads the
   toggle engine's own --toggle-count, seeded inline at build. */
.fieldset-locations-toggle {
    grid-template-columns: repeat(var(--toggle-count, 3), 1fr);
}

/* The venue's address wrap (display + hidden input) is text, not an input:
   the green status line follows it directly — no margin. */
.fieldset-location-inputwrap:has(.fieldset-venue-address-display) {
    margin-bottom: 0;
}

.fieldset-location-inputwrap--open {
    z-index: var(--layer-menu, 85);
}

/* When dropdown is open, connect input to dropdown visually */
.fieldset-location-inputwrap--open .input-class-1 {
    border-color: var(--blue-500);
    border-bottom: none;
    border-radius: 8px 8px 0 0;
}

/* Location dropdown (New Google Places AutocompleteSuggestion UI)
   Appearance governed by menu-class-2 from base.css.
   This section contains LAYOUT ONLY. */
.fieldset-location-dropdown {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    z-index: var(--layer-menu, 85);
    max-height: 200px;
    overflow-y: auto;
}

.fieldset-location-dropdown-item {
    display: block;
    width: 100%;
    background: transparent;
    background-image: none; /* Reset any browser defaults */
    border: none;
    padding: 10px;
    text-align: left;
    cursor: pointer;
    color: #fff;
    line-height: 1.4;
    transition: background 0.2s ease;
    box-sizing: border-box;
}

.fieldset-location-dropdown-item:hover,
.fieldset-location-dropdown-item.menu-item--active {
    background: rgba(255, 255, 255, 0.1);
}

.fieldset-location-dropdown-item-main {
    display: block;
    font-weight: 600;
    font-size: 14px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
}

.fieldset-location-dropdown-item-secondary {
    display: block;
    font-size: 12px;
    color: rgba(255, 255, 255, 0.6);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 2px;
    pointer-events: none;
}

/* Venue fieldset: address "secret input" (click to edit).
   No vertical padding, no fixed height (operator 2026-08-24): the address is
   simply the next line of text, and the green status line follows directly —
   identical whether the address wraps or not. */
.fieldset-venue-address-display {
    display: flex;
    align-items: center;
    padding: 0 10px;
    line-height: 1.4;
    color: rgba(255,255,255,0.75);
    cursor: pointer;
    user-select: none;
    background: transparent;
    border: none;
    /* Venue receipt puts the name and address on separate lines via a
       newline in textContent (operator 2026-09-06); city/address receipts
       carry no newline, so they render exactly as before. */
    white-space: pre-line;
}

.fieldset-venue-address-display:hover {
    color: rgba(255,255,255,0.9);
    text-decoration: underline;
    text-decoration-style: dotted;
    text-decoration-color: rgba(255,255,255,0.3);
}

.fieldset-venue-address-display--hidden {
    display: none;
}

.fieldset-venue-address-input--hidden {
    display: none;
}


/* ============================================================================
   GOOGLE PLACES (External Library)
   ============================================================================ */

.pac-container {
    /* Google Places external dropdown - matches menu-class-2 appearance */
    background: rgba(0, 0, 0, 0.35);
    border: 1px solid var(--blue-500);
    border-radius: 8px;
    font-size: 13px;
    z-index: var(--layer-menu, 85);
    box-shadow: 0 6px 18px rgba(0,0,0,0.35);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    transform: translateY(10px);
}

.pac-item {
    padding: 8px 10px;
    color: #fff;
    cursor: pointer;
    border-top: 1px solid #333;
}

.pac-item:first-child {
    border-top: none;
}

.pac-item:hover,
.pac-item-selected {
    background: rgba(255, 255, 255, 0.1);
    color: #fff;
}

.pac-item-query {
    color: #fff;
    font-weight: bold;
}

.pac-matched {
    color: var(--blue-500);
}

.pac-icon {
    display: none;
}

/* ============================================================================
   TICKET PRICING FIELDSET
   ============================================================================ */

/* Ticket Pricing fieldset overrides */
.fieldset[data-fieldset-key="ticket-pricing"] {
    margin-bottom: 0;
}

.fieldset[data-fieldset-key="ticket-pricing"] > .fieldset-label {
    margin-bottom: 0;
}

/* Instruction Text - uses generic .fieldset-instruction class */

/* Ticket Groups Container */
.fieldset-ticketpricing-ticketgroups-container {
    width: 100%;
    margin-bottom: 10px; /* 10px to the "+ Add Group" beneath (operator 2026-09-11) */
    box-sizing: border-box;
}

/* Ticket Group Item */
.fieldset-ticketpricing-ticketgroup-item {
    margin-bottom: 10px;
}

.fieldset-ticketpricing-ticketgroup-item:last-child {
    margin-bottom: 0;
}

.fieldset-ticketpricing-ticketgroup-item-header-content {
    display: flex;
    align-items: center;
    height: 36px;
    padding: 0 0 0 10px;
    gap: 6px;
    cursor: pointer;
}

/* Ticket icon prefix on the accordion header — same 24px size as the
   sessions Ticket Pricing summary rows so the two touch-points share
   one visual marker (the sessions row group dropdown stays 18px). */
.fieldset-ticketpricing-ticketgroup-header-icon {
    width: 24px;
    height: 24px;
    object-fit: contain;
    flex-shrink: 0;
}

.fieldset-ticketpricing-ticketgroup-header-label {
    flex: 1;
    font-size: 13px;
    font-weight: 500;
}

/* Single-group state — JS sets data-group-count="1" on the fieldset
   whenever exactly one ticket group exists. The header reads "Tickets"
   (label text set in tpSyncGroupCountAttr) and keeps the ticket icon +
   Add button, but drops the chevron and the remove button — there's
   nothing to collapse or remove with a single group. The header-content
   also stops being clickable (matches the JS click-handler short-circuit
   in tpEnsureTicketGroup) so the user can't accidentally try to collapse
   the only group. The editor body is forced visible via the existing
   accordion-class-1 open-state machinery, which tpSyncGroupCountAttr keeps
   applied whenever the count drops to 1. */
.fieldset[data-fieldset-key="ticket-pricing"][data-group-count="1"] .fieldset-ticketpricing-ticketgroup-arrow,
.fieldset[data-fieldset-key="ticket-pricing"][data-group-count="1"] .fieldset-ticketpricing-ticketgroup-button-remove {
    display: none;
}
.fieldset[data-fieldset-key="ticket-pricing"][data-group-count="1"] .fieldset-ticketpricing-ticketgroup-item-header-content {
    cursor: default;
}
/* Without the label (which carries flex: 1 in multi-group state) the
   Add button would sit immediately to the right of the ticket icon
   on the left. margin-left: auto on a flex item is the standard
   "push to far right" idiom — it consumes all the freed horizontal
   space so the Add button anchors to the right edge of the header. */
.fieldset[data-fieldset-key="ticket-pricing"][data-group-count="1"] .fieldset-ticketpricing-ticketgroup-button-add {
    margin-left: auto;
}

.fieldset-ticketpricing-ticketgroup-arrow {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fieldset-ticketpricing-ticketgroup-arrow-icon {
    width: 16px;
    height: 16px;
    background-color: currentColor;
    -webkit-mask-image: var(--ui-icon-arrow-down);
    mask-image: var(--ui-icon-arrow-down);
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    transition: transform 0.2s;
    transform-origin: center;
}

.fieldset-ticketpricing-ticketgroup-item.accordion-class-1--open .fieldset-ticketpricing-ticketgroup-arrow-icon {
    transform: rotate(180deg);
}

.fieldset-ticketpricing-ticketgroup-button-add,
.fieldset-ticketpricing-ticketgroup-button-remove {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    cursor: pointer;
    margin-left: 4px;
}

.fieldset-ticketpricing-ticketgroup-button-add .fieldset-ticketpricing-ticketgroup-button-icon,
.fieldset-ticketpricing-ticketgroup-button-remove .fieldset-ticketpricing-ticketgroup-button-icon {
    width: 18px;
    height: 18px;
    object-fit: contain;
}

.fieldset-ticketpricing-ticketgroup-item-editorwrap {
    overflow: hidden;
}

.fieldset-ticketpricing-ticketgroup-item.accordion-class-1--open .fieldset-ticketpricing-ticketgroup-item-editorwrap {
    padding: 10px;
}

/* Editor body - hidden by default, shown when open */
.fieldset-ticketpricing-ticketgroup-item-editorwrap {
    display: none;
    padding: 10px;
}

.fieldset-ticketpricing-ticketgroup-item.accordion-class-1--open .fieldset-ticketpricing-ticketgroup-item-editorwrap {
    display: block;
}

.fieldset-ticketpricing-ticketgroup-item--active .accordion-header {
    border-color: var(--blue-500);
}

.fieldset-ticketpricing-ticketgroup-item--active.accordion-class-1--open .accordion-body {
    border-color: var(--blue-500);
}

/* Promo Preview Active State — --green-600 is the site's canonical promo green
   (matches .post-session-ticket-price-promo + .post-session-promo-badge in
   components.css); reads on both themes so no light-theme override needed. */
.fieldset-ticketpricing-promo-preview-active .fieldset-ticketpricing-input-ticketarea,
.fieldset-ticketpricing-promo-preview-active .fieldset-ticketpricing-tier-input-row input.fieldset-input,
.fieldset-ticketpricing-promo-preview-active .fieldset-ticketpricing-input-price {
    border-color: var(--green-600);
    color: var(--green-600);
}

.fieldset-ticketpricing-promo-preview-active .fieldset-ticketpricing-ticketarea-label-row .fieldset-sublabel,
.fieldset-ticketpricing-promo-preview-active .fieldset-ticketpricing-tier-label-row .fieldset-sublabel {
    color: var(--green-600);
}

/* Item Pricing Promo Preview Active State */
.fieldset-itempricing-promo-preview-active .fieldset-itempricing-input-itemname,
.fieldset-itempricing-promo-preview-active .component-ageratingpicker-menu-button,
.fieldset-itempricing-promo-preview-active .fieldset-itempricing-menu-currency .menu-button,
.fieldset-itempricing-promo-preview-active .fieldset-itempricing-input-itemprice {
    border-color: var(--green-600);
    color: var(--green-600);
}

.fieldset-itempricing-promo-preview-active .fieldset-itempricing-sublabel-itemname,
.fieldset-itempricing-promo-preview-active .fieldset-itempricing-sublabel-agerating,
.fieldset-itempricing-promo-preview-active .fieldset-itempricing-sublabel-currency,
.fieldset-itempricing-promo-preview-active .fieldset-itempricing-sublabel-itemprice {
    color: var(--green-600);
}

/* ============================================================================
   SESSIONS FIELDSET
   ============================================================================ */

/* Instruction Text - uses generic .fieldset-instruction class */

/* Sessions Container */
.fieldset-sessions-sessions-container {
    display: flex;
    flex-direction: column;
}

.fieldset-sessions-session-container-item {
    display: flex;
    flex-direction: column;
}

.fieldset-sessions-session-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Date input box */
.fieldset-sessions-session-field-label {
    flex: 1;
    height: 36px;
    padding: 0 10px;
    font-size: 13px;
    display: flex;
    align-items: center;
}

.fieldset-sessions-session-field-label-spacer {
    flex: 1;
    height: 36px;
}

.fieldset-sessions-session-field-time {
    /* Fixed 55px. The time text auto-fits via a container-query font (on the
       input below), copying the session-menu doorway button's approach
       (post.css .post-sessionmenu-button): the box is the measuring container,
       so the widest value (23:58) shrinks to fit rather than clipping — no
       wider box needed (operator 2026-07-14). */
    flex: 0 0 55px;
    container-type: inline-size;
}

/* ==========================================================================
   SET-TIME WINDOW (two-window system, 2026-07-14)
   Transient modal over the create-post panel — mounted into .member-panel-contents
   so it covers the panel, not the whole screen (dialogs do full screen). Card
   matches the dialog look (#222 dark here / #fff light in themes.css). Escape /
   click-away / Cancel abandon; the three Apply-to buttons commit and close.
   ========================================================================== */
.fieldset-sessions-timepickermodal-overlay {
    position: absolute;
    inset: 0;
    z-index: var(--layer-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px;
    background: rgba(0, 0, 0, 0.45);
    box-sizing: border-box;
    /* The panel chain is pointer-events:none (transparent panel over the map),
       so re-enable events here or every click/scroll falls through to the map. */
    pointer-events: auto;
}
.fieldset-sessions-timepickermodal {
    width: 280px;
    max-width: 100%;
    background: #222222;
    color: #fff;
    border-radius: 8px;
    box-shadow: 0 20px 45px rgba(0, 0, 0, 0.5);
    overflow: hidden;
    box-sizing: border-box;
}
/* Border + header/content surfaces come from container-class-2 (the location
   container). This class only lays out the header row inside it. */
.fieldset-sessions-timepickermodal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 36px;
    padding: 0 6px 0 10px;
}
.fieldset-sessions-timepickermodal-header-icon {
    width: 18px;
    height: 18px;
    margin-right: 10px;
    flex: 0 0 auto;
}
.fieldset-sessions-timepickermodal-header-label {
    font-size: 14px;
    font-weight: 500;
    margin-right: auto; /* hugs the icon on the left, pushes the close X to the right */
}
.fieldset-sessions-timepickermodal-close {
    background: transparent;
    border: none;
    color: var(--website-white);
    font-size: 22px;
    line-height: 1;
    padding: 0 6px;
    cursor: pointer;
}
.fieldset-sessions-timepickermodal-wheelrow {
    display: flex;
    align-items: stretch;
    justify-content: center;
    gap: 0;
    padding: 10px;
    height: 150px;
    box-sizing: border-box;
    position: relative; /* anchors the centre band */
}
.fieldset-sessions-timepickermodal-colon {
    display: flex;
    align-items: center;
    font-size: 22px;
    font-weight: 500;
    padding: 0 6px; /* breathing room between each hugged digit and the colon */
}
/* Visible native spin wheel (operator 2026-07-14): each column is a REAL
   overflow-scroll list of numbers — the finger spins it with native momentum and
   the value is read off the scroll position. Fades top/bottom; the selected row is
   marked by the centre band. touch-action:pan-y so the finger can spin it, and no
   ancestor may set touch-action:none or the browser refuses to scroll it. */
.fieldset-sessions-timepickermodal-wheel {
    flex: 1;
    box-sizing: border-box; /* padding stays inside the stretched height so the seed maths holds */
    overflow-y: scroll;
    scroll-snap-type: y mandatory;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    touch-action: pan-y;
    scrollbar-width: none;
    text-align: center;
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 35%, #000 65%, transparent);
            mask-image: linear-gradient(to bottom, transparent, #000 35%, #000 65%, transparent);
}
.fieldset-sessions-timepickermodal-wheel::-webkit-scrollbar {
    display: none;
}
/* Focused (clicked / Tabbed) column tints so it is clear which segment the
   typed digits and arrow keys will land on. */
.fieldset-sessions-timepickermodal-wheel:focus {
    outline: none;
    background: rgba(255, 255, 255, 0.06);
}
.fieldset-sessions-timepickermodal-wheel-item {
    height: 40px; /* MUST match itemHeight in fieldsets.js */
    line-height: 40px;
    scroll-snap-align: center;
    font-size: 22px;
    font-weight: 500;
    color: #fff;
    box-sizing: border-box;
}
.fieldset-sessions-timepickermodal-wheelband {
    position: absolute;
    left: 10px;
    right: 10px;
    top: 50%;
    height: 40px;
    transform: translateY(-50%);
    border-top: 1px solid rgba(255, 255, 255, 0.15);
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
    pointer-events: none;
}
.fieldset-sessions-timepickermodal-applytolabel {
    font-size: 12px;
    color: rgba(255, 255, 255, 0.6);
    padding: 0 10px 6px;
}
.fieldset-sessions-timepickermodal-applyto {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 0 10px 10px;
}
.fieldset-sessions-timepickermodal-applyto-button {
    width: 100%;
}

/* ==========================================================================
   SESSION TIME DELETE MODAL (two-window system, 2026-07-14)
   Centered danger dialog (dialogs centre on the whole screen; only the picker
   sits over the panel). Card matches the dialog look; header is danger-red.
   ========================================================================== */
.fieldset-sessions-timedeletemodal-overlay {
    position: absolute;
    inset: 0;
    z-index: var(--layer-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px;
    background: rgba(0, 0, 0, 0.45);
    box-sizing: border-box;
    pointer-events: auto;
}
.fieldset-sessions-timedeletemodal {
    width: 300px;
    max-width: 100%;
    background: #222222;
    color: #fff;
    border-radius: 8px;
    box-shadow: 0 20px 45px rgba(0, 0, 0, 0.5);
    overflow: hidden;
    box-sizing: border-box;
}
/* Border + red header + content surface come from container-class-4 (the red
   copy of the location container). This class only lays out the header row. */
.fieldset-sessions-timedeletemodal-header {
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 6px 0 10px;
    font-size: 14px;
    font-weight: 500;
}
.fieldset-sessions-timedeletemodal-header-icon {
    width: 18px;
    height: 18px;
    margin-right: 10px;
    flex: 0 0 auto;
}
.fieldset-sessions-timedeletemodal-header-label {
    font-size: 14px;
    font-weight: 500;
    margin-right: auto; /* hugs the icon on the left, pushes the close X to the right */
}
.fieldset-sessions-timedeletemodal-close {
    background: transparent;
    border: none;
    color: var(--website-white);
    font-size: 22px;
    line-height: 1;
    padding: 0 6px;
    cursor: pointer;
}
.fieldset-sessions-timedeletemodal-options {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px;
}
.fieldset-sessions-timedeletemodal-option {
    width: 100%;
}

/* ==========================================================================
   SESSIONS UNDO / REDO / CLEAR ROW (two-window system, 2026-07-14)
   Undo/Redo icons on the left, Clear on the right; 10px below the calendar and
   10px above the times table.
   ========================================================================== */
.fieldset-sessions-controls-row,
.fieldset-timelines-controls-row {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 10px 0;
}
.fieldset-sessions-controls-icon,
.fieldset-timelines-controls-icon {
    width: 36px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.fieldset-sessions-controls-icon:disabled,
.fieldset-timelines-controls-icon:disabled {
    opacity: 0.4;
    cursor: default;
}
/* Mask glyphs filled with currentColor (admin icons via --ui-icon-*), so they
   match the button text colour and theme automatically — same technique as the
   +/- AddRemove icons. */
.fieldset-sessions-controls-glyph,
.fieldset-timelines-controls-glyph {
    display: inline-block;
    width: 18px;
    height: 18px;
    background-color: currentColor;
    -webkit-mask: center / contain no-repeat;
    mask: center / contain no-repeat;
}
.fieldset-sessions-controls-glyph--undo,
.fieldset-timelines-controls-glyph--undo {
    -webkit-mask-image: var(--ui-icon-undo);
    mask-image: var(--ui-icon-undo);
}
.fieldset-sessions-controls-glyph--redo,
.fieldset-timelines-controls-glyph--redo {
    -webkit-mask-image: var(--ui-icon-redo);
    mask-image: var(--ui-icon-redo);
}
.fieldset-sessions-controls-clear,
.fieldset-timelines-controls-clear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
/* Fills the space between Redo and Clear and centres its own text, so it sits
   equidistant from both. Height/line-height 36px match the buttons so the text
   sits at the same altitude; font-size inherits (same as the buttons). */
.fieldset-sessions-controls-count,
/* Dates | Time Blocks pill — toggle-class-1 wearer (operator 2026-09-22). Every
   wearer supplies its own grid columns (the Location Type toggle above); two
   halves, read off the engine's --toggle-count, seeded inline at build. */
.fieldset-timelines-modeswitch-toggle {
    grid-template-columns: repeat(var(--toggle-count, 2), 1fr);
}

/* The fraction rides the Time Blocks half of the pill (operator 2026-09-22),
   after the word: "Time Blocks 21/21 ●". It was the undo row's centre. */
.fieldset-timelines-controls-count {
    margin-left: 6px;
    white-space: nowrap;
    /* The button's own colour (operator 2026-09-22: the fraction read dark on
       the pressed grey pill in light theme) — white when pressed, dimmed
       when not, in both themes, exactly as the word beside it. */
    color: inherit;
}

/* The complete dot on the pill wears the word's colour too (operator 2026-09-22,
   light-theme screenshot: the light twin's black dot sat beside white words on
   the pressed grey slider) — white when pressed, dimmed when not, in both
   themes. The incomplete dot stays the system red. */
.fieldset-timelines-modeswitch-toggle .fieldset-label-required--complete {
    color: inherit;
}

/* Dates / Times switch, alone at the right end of the undo row (operator
   2026-09-19): wider than the icon buttons because it carries the word. */
/* NARROW SCREENS (operator 2026-09-19): the count is the only thing that
   gives. Without this the flex row squeezed the BUTTONS instead — 36px icons
   down to 31 and the switch to 72 — and the squeeze changed as the number
   grew ("0/44" to "44/44"), so the row shifted while you filled times. The
   buttons hold their size; the count truncates. */
.fieldset-timelines-controls-row > .fieldset-timelines-controls-icon,
.fieldset-timelines-controls-row > .fieldset-timelines-controls-clear,
.fieldset-timelines-controls-row > .fieldset-timelines-controls-clear {
    flex-shrink: 0;
}

/* (The modeswitch carets retired 2026-09-22: Dates | Time Blocks | Close
   stand side by side with no arrows.) */

/* The count's completeness dot: the same 3px lift the container bar's dot
   uses, so its ink centres on the words rather than riding their baseline,
   and its own line box instead of the row's 36px one (operator 2026-09-19). */
.fieldset-timelines-controls-count .fieldset-label-required {
    position: relative;
    top: -3px;
    line-height: normal;
}

/* THE INSTRUCTION LINE IN THE UNDO ROW (operator 2026-09-22): it took the
   fraction's seat between Redo and Clear — one 13px line, centred, that
   truncates before the buttons ever give (the narrow-screen rule above).
   Pane-scoped to outrank the time-mode breathing rule further down. */
.fieldset-timelines-pane-container .fieldset-timelines-controls-row > .fieldset-timelines-tools-instruction-row {
    flex: 1;
    min-width: 0;
    height: 36px;
    line-height: 36px;
    margin-bottom: 0;
    /* Left-aligned after 10px (operator 2026-09-22), not centred, and 600
       like the umbrella headlines (operator, later that night: louder
       without capitals). */
    padding: 0 0 0 10px;
    text-align: left;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fieldset-sessions-session-field-time-input {
    width: 100%;
    height: 36px;
    padding: 0 10px;
    /* Font auto-fits the 55px box, copying post.css:2511
       (.post-sessionmenu-button .post-menubutton-sub): the font scales with the
       box's real width (container-query) so the widest value fits without
       clipping — 13px ceiling, 11px floor. Worst case is 00:00, NOT 23:58 —
       "0" is the widest digit in the site font (operator 2026-07-14); 20.5cqw
       is held under the exact fit so even 00:00 keeps a small right margin. */
    font-size: clamp(11px, 20.5cqw, 13px);
    text-align: center;
    /* iOS gives <input type="time"> an intrinsic minimum width that
       overrides width:100%, shoving the box over the + button. min-width
       lets it obey the 55px column, and appearance:none strips Safari's
       native widget layer so width/padding rules actually apply. */
    min-width: 0;
    -webkit-appearance: none;
    appearance: none;
}

/* iOS renders the time value in this internal element with its own
   margin — zero it and center so the digits sit like the desktop input. */
.fieldset-sessions-session-field-time-input::-webkit-date-and-time-value {
    margin: 0;
    text-align: center;
}

.fieldset-sessions-session-field-time-input::-webkit-calendar-picker-indicator {
    filter: invert(1);
    cursor: pointer;
}

/* Ticket Group Button */
.fieldset-sessions-ticketgroup-button-toggle {
    flex: 0 0 80px;
    width: 80px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    position: relative;
    box-sizing: border-box;
    padding: 0 10px;
    /* 5px between icon, letter and arrow (operator 2026-07-07). */
    gap: 5px;
}

.fieldset-sessions-ticketgroup-button-icon {
    width: 18px;
    height: 18px;
    object-fit: contain;
    flex-shrink: 0;
}

.fieldset-sessions-ticketgroup-button-label {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 700;
    color: #fff;
    pointer-events: none;
    /* Fills the middle so the arrow pins to the right edge — same
       structure as the age rating picker button (menu-text flex). */
    flex: 1;
}

/* Dropdown arrow on the toggle — sizing copied from
   .component-ageratingpicker-menu-button-arrow (components.css). */
.fieldset-sessions-ticketgroup-button-arrow {
    width: 16px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
}

/* Ticket Group Dropdown Menu — 80px: 10px padding each side + 18px icon
   + 16px arrow + the letter, 5px apart (operator 2026-07-07); was 70px
   before the arrow existed. */
.fieldset-sessions-ticketgroup-menu {
    position: relative;
    flex: 0 0 80px;
    width: 80px;
}

.fieldset-sessions-ticketgroup-menu-options {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: var(--layer-menu, 85);
}

/* Drawer animation: height/overflow on outer via base.css :has() rule.
   Appearance (background + border) comes from the base.css menu-class-1
   hoist rule (theme-variable driven, so light theme flips for free —
   operator 2026-07-07); only max-height + scrolling live here so the
   dropdown slides in/out as a single unit. */
.fieldset-sessions-ticketgroup-menu.menu-class-1 .fieldset-sessions-ticketgroup-menu-options > .menu-options-inner {
    max-height: 200px;
    overflow-y: auto;
}

.fieldset-sessions-ticketgroup-menu-option {
    width: 100%;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    padding: 0 10px;
    background: transparent;
    border: none;
    color: #fff;
    font-size: 13px;
    cursor: pointer;
    white-space: nowrap;
}

.fieldset-sessions-ticketgroup-menu-option:hover {
    background: var(--blue-500);
}

.fieldset-sessions-ticketgroup-menu-option-icon {
    width: 18px;
    height: 18px;
    object-fit: contain;
}

.fieldset-sessions-ticketgroup-menu-option-label {
    font-size: 12px;
    font-weight: 700;
}

/* Sessions calendar — permanently visible at the top of the fieldset
   (no longer a popover). Sits between the instruction text and the
   sessions list, with standard 10px element spacing below.
   Idle state uses a muted gray border; the bright blue accent only
   appears once the user has clicked into the calendar (focused state
   toggled by JS via pointerdown inside/outside the container). */
.fieldset-sessions-calendar-container {
    margin-bottom: 10px;
    border-color: #333;
}

/* A GHOST CALENDAR since 2026-09-20 (fieldsets.js sessBuildCalendar). Every
   colour it used to set here — the square fills, the archive-grey box of an
   ended session date, the "never react" paint of a dead past date — now comes
   from THE CALENDAR DATE REGISTRY (ghostcalendar.css names this container).
   AN ENDED SESSION DATE is the registry's Past active: a WEBSITE-grey circle,
   the same as the timelines picker beside it (operator 2026-09-20: archive
   grey belongs to archived posts only). It stays tappable — the tap raises the
   remove-archival-date warning (fieldsets.js). */
.fieldset-sessions-calendar-container--focused {
    border-color: var(--blue-500);
}

/* A past date with NO sessions is dead: the plain arrow, and the registry gives
   it no hover term, so it never reacts (was a block of "kill the hover" paints). */
.fieldset-sessions-calendar-container .ghostcalendar-day.past:not(.selected) {
    cursor: default;
}

/* The ghost calendar's own blue line under itself would double against the
   frame's bottom edge (the timelines picker's same rule, further down). */
.fieldset-sessions-calendar-container .ghostcalendar-wrapper {
    border-bottom: none;
}

/* It names its ground, so its dates wear THE DATE OUTLINE (base.css): the
   .calendar-container frame's #222, white in light — the menus' pair. */
.fieldset-sessions-calendar-container .ghostcalendar-grid .ghostcalendar-day {
    --calendardate-ground: var(--calendardate-menu-ground);
}

/* THE WEEKDAYS WEAR THE SOLID BLUE BAND (operator 2026-09-20, shown the old
   calendar's blue header: "it will look better with the blue") — the coupon
   and filter pickers' band, white writing in both themes (twin in themes.css). */
.fieldset-sessions-calendar-container .ghostcalendar-wrapper .ghostcalendar-weekdays {
    background: var(--blue-900);
}

.fieldset-sessions-calendar-container .ghostcalendar-weekday {
    color: #ffffff;
}

/* Empty-state hint, shown inside the sessions container when no dates
   have been picked from the calendar above. */
.fieldset-sessions-empty-hint {
    margin: 0;
    font-size: 13px;
    color: rgba(255, 255, 255, 0.6);
}

/* Ticket Pricing summary section — sits as a sibling directly above
   the sessions fieldset (not nested inside it). Contains: standard
   label + completeness dot (6px gap to button is baked into
   .fieldset-label), plus one full-width row-button per ticket group.
   Each row IS the entry point — clicking it opens the Ticket Pricing
   Modal pre-focused on that group. 12px bottom margin separates the
   section from the sessions fieldset below, matching the sibling-
   container rule. */
.fieldset-sessions-tp-section {
    margin-bottom: 10px;
}

/* Legend = a column of full-width row-buttons, each one a clickable
   entry to the Ticket Pricing Modal pre-focused on its group. Rows
   share the parent grid's column tracks via `subgrid`, so the inner
   cells (ticket / price / age / promo) line up vertically across
   every row — promo badges stay the same width as the widest, age
   icons line up, etc. Column layout left → right:
     1. ticket icon + "Group X"    (auto)
     2. price range / prompt       (1fr — absorbs slack so rows are full width)
     3. age rating icon            (auto)
     4. promo badge                (auto — collapses to 0 when no row has one)
   Row gap matches the 8px session-row spacing. */
.fieldset-sessions-tp-legend {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    column-gap: 10px;
    row-gap: 8px;
    align-items: center;
}

/* Each row spans every column of the parent and re-uses those tracks
   via subgrid so cross-row alignment is automatic. First/last cells
   carry 10px side padding instead of the button itself so subgrid
   stays in lockstep with the parent (padding on the button would
   inset the subgrid tracks). button-class-4 supplies background,
   border, color, cursor and focus chrome. */
.fieldset-sessions-tp-legend-row {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: subgrid;
    column-gap: 10px;
    align-items: center;
    height: 36px;
    padding: 0;
    text-align: left;
    box-sizing: border-box;
}
.fieldset-sessions-tp-legend-row > .fieldset-sessions-tp-legend-ticket {
    padding-left: 10px;
}
.fieldset-sessions-tp-legend-row > .fieldset-sessions-tp-legend-promo {
    padding-right: 10px;
}

.fieldset-sessions-tp-legend-ticket {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.fieldset-sessions-tp-legend-ticket-icon {
    width: 24px;
    height: 24px;
    object-fit: contain;
}

.fieldset-sessions-tp-legend-ticket-label {
    font-size: 13px;
    /* Half-bold (operator 2026-07-07) — same medium weight as the Ticket
       Group accordion header label. */
    font-weight: 500;
    color: #fff;
}

/* Single-group state — the "Group X" text disappears so the lone row
   reads as just "this is your ticket pricing", not "this is one of
   several groups". :only-child auto-keys on row count, no JS flag
   needed: as soon as a second tp group exists the legend gets a
   second row, :only-child stops matching, and the label returns. */
.fieldset-sessions-tp-legend-row:only-child .fieldset-sessions-tp-legend-ticket-label {
    display: none;
}

.fieldset-sessions-tp-legend-age {
    display: inline-flex;
    align-items: center;
}

/* The age icon stands as tall as the promo badge beside it (operator
   2026-09-11): both 20px - the badge's 12px line plus its 2px pads. */
.fieldset-sessions-tp-legend-age-icon {
    width: auto;
    height: 20px;
    object-fit: contain;
}

.fieldset-sessions-tp-legend-price {
    font-size: 13px;
    color: #fff;
    white-space: nowrap;
}

/* "Set ticket prices" prompt that replaces the price range for the
   truly-fresh Group A (no data anywhere yet). Slightly faded + italic
   so it reads as a call-to-action rather than data. */
.fieldset-sessions-tp-legend-price--prompt {
    color: rgba(255, 255, 255, 0.6);
    font-style: italic;
}

/* Promo cell is a flex container so the badge inside can stretch to
   fill it. The cell itself stretches to fill its grid column (default
   justify-self: stretch on grid items), and the column auto-sizes to
   the widest badge — so every badge across rows ends up the same
   width as the widest one, with shorter codes simply left-aligned
   inside an identical green rectangle. */
.fieldset-sessions-tp-legend-promo {
    display: flex;
    align-items: center;
}

/* Scaled-down twin of .post-session-promo-badge from components.css
   (live post promo display). Same green background + white text + bold
   weight + letter-spacing, with reduced padding/font so the badge
   sits cleanly inside the 24px-ish legend row height. `flex: 1` makes
   the pill fill the cell width so the green rectangle is uniform
   across rows; `justify-content: flex-start` keeps the text left-
   aligned inside. */
.fieldset-sessions-tp-legend-promo-badge {
    flex: 1;
    display: block;
    height: 20px;
    line-height: 16px;
    padding: 2px 8px;
    background: var(--green-600);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    border-radius: 4px;
    letter-spacing: 0.02em;
    white-space: nowrap;
    box-sizing: border-box;
    /* TRUNCATION (operator 2026-09-05): a long promo code was shoving the
       whole legend row and chopping the right side off — the badge caps
       and ellipsizes instead; the live post shows the full code. */
    max-width: 150px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ============================================================================
   SESSIONS SUMMARY
   One per location container — sits in the slot the (now-hidden) sessions
   fieldset would have occupied. Standard fieldset shape (.fieldset + .fieldset-
   label) so the existing renumberLocationContainers system in formbuilder.js
   auto-suffixes the label as "Sessions 1 / 2 / 3" when there are multiple
   locations, and drops the suffix when only one location remains. The body is
   a single full-width button showing the location's date range — clicking it
   fires `sessions:request-modal` which the host (Edit Modal / Create Post)
   forwards to openSessionsModal.
   ============================================================================ */

/* Single full-width button — same chrome as the tp legend rows so the two
   summaries read as a matched pair stacked above and below. button-class-4
   supplies background, border, color, cursor and focus chrome. The 6px gap
   (icon ↔ text) matches the tp legend's `gap: 6px` between ticket icon and
   "Group X" label. */
.fieldset-sessions-summary-row {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    height: 36px;
    padding: 0 10px;
    text-align: left;
    box-sizing: border-box;
    width: 100%;
}

/* Calendar icon cell — fixed 18x18 square (same size as the tp legend's
   ticket icon) so the date text starts at the same x-position regardless
   of whether the icon image has finished loading. */
.fieldset-sessions-summary-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
}

.fieldset-sessions-summary-icon-img {
    width: 18px;
    height: 18px;
    object-fit: contain;
}

/* Date range / prompt text — same font + color as the tp legend price cell. */
.fieldset-sessions-summary-text {
    font-size: 13px;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* "Select Session times" prompt for the empty state. Matches the tp prompt
   modifier — slightly faded + italic so it reads as a call-to-action rather
   than data. */
/* FILL PENDING (operator 2026-09-15, Post Editor load order): a podal
   summary button waiting for its load-3 fill shows the fieldset icon and,
   10px to its right, the site's 13px ring — nothing else. Worn by every
   summary row (sessions / links / amenities / item pricing / timelines);
   the ring recipe is base.css's one declaration, this sets size + place:
   10px pad + 18px icon + 10px gap = 38px from the left edge. Light twin
   (dark ring on the white button) in themes.css. */
.fieldset-summary-pending {
    position: relative;
}
.fieldset-summary-pending::after {
    --loadingring-size: 13px;
    top: 50%;
    left: 38px;
    margin-top: -6.5px;
}

.fieldset-sessions-summary-text--prompt {
    color: rgba(255, 255, 255, 0.6);
    font-style: italic;
}

/* ============================================================================
   AMENITIES SUMMARY (in-form, location-specific)
   ----------------------------------------------------------------------------
   Mirrors .fieldset-sessions-summary: a stand-in fieldset placed immediately
   above the (CSS-hidden) `[data-fieldset-key="amenities"]` host fieldset
   inside each location container. The body is a single button — clicking it
   fires `amenities:request-modal` which the host (Edit Modal / Create Post)
   forwards to openAmenitiesModal. The button itself has no fixed height —
   it grows to fit one row of 24×24 icons (~44px tall) and wraps onto a
   second row when the icon count exceeds the available width.
   ============================================================================ */

/* Wrapping icon strip — same chrome as the sessions summary (button-class-4)
   so the two summaries read as a matched pair when they appear together
   inside the same location container. flex-wrap matches the post panel's
   .post-amenities-container. min-height: 36px keeps the empty-state button
   from collapsing flat when only the prompt text is shown. */
.fieldset-amenities-summary-row {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    flex-wrap: wrap;
    min-height: 36px;
    padding: 10px;
    text-align: left;
    box-sizing: border-box;
    width: 100%;
}

/* Each amenity tile — 24×24 to match the host fieldset's row icon size
   exactly so the user recognises the same icons at the same scale they
   touched while editing. The tile itself is the icon area (no extra
   chrome around it); the white/grey state lives on the inner mask. */
.fieldset-amenities-summary-item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex: 0 0 24px;
}

/* Mask-image render — mirrors .post-amenities-icon. The icon URL is set
   per-tile via the `--fieldset-amenities-summary-mask` custom property
   so we keep one CSS rule for every amenity. White for Yes (active),
   45% white for No (inactive). Unset amenities are not rendered at all
   in the summary — the completeness dot tells the user when the
   fieldset has untouched rows. */
.fieldset-amenities-summary-icon {
    width: 24px;
    height: 24px;
    display: block;
    background-color: #555;
    -webkit-mask-image: var(--fieldset-amenities-summary-mask);
    mask-image: var(--fieldset-amenities-summary-mask);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
}

.fieldset-amenities-summary-item--active .fieldset-amenities-summary-icon {
    background-color: #fff;
}

/* Empty-state prompt — same colour and slant as the sessions and tp
   prompts so the three summaries hand-off to the user identically. */
.fieldset-amenities-summary-text {
    font-size: 13px;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.fieldset-amenities-summary-text--prompt {
    color: rgba(255, 255, 255, 0.6);
    font-style: italic;
}

/* ============================================================================
   LOCATIONS SUMMARY (in-form, post-level — operator 2026-09-08)
   ----------------------------------------------------------------------------
   One row per form, directly above the location containers. Clicking fires
   `locations:request-modal` → openLocationsModal (postmanager.js), which
   physically moves the containers into the Locations Modal. Same chrome as
   .fieldset-amenities-summary-row above (flex copied from that matched pair). */
.fieldset-locations-summary {
    margin-bottom: 12px;
}

.fieldset-locations-summary-row {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    min-height: 36px;
    padding: 10px;
    text-align: left;
    box-sizing: border-box;
    width: 100%;
}

/* ============================================================================
   LINKS SUMMARY (in-form, post-level)
   ----------------------------------------------------------------------------
   Mirrors .fieldset-amenities-summary above: a stand-in fieldset placed
   immediately above the (CSS-hidden) `[data-fieldset-key="links"]` host
   fieldset. Clicking fires `links:request-modal` → openLinksModal. Filled
   state = one 24×24 mask tile per selected link type (icons only, no URLs
   — operator 2026-09-04); empty state = the fieldset_prompt italic line.
   ============================================================================ */

/* 36px like every other summary row (operator 2026-09-11) - the icon
   strip runs on one line and clips rather than wrapping. */
.fieldset-links-summary-row {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    flex-wrap: nowrap;
    overflow: hidden;
    height: 36px;
    padding: 0 10px;
    text-align: left;
    box-sizing: border-box;
    width: 100%;
}

.fieldset-links-summary-item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex: 0 0 24px;
}

.fieldset-links-summary-icon {
    width: 24px;
    height: 24px;
    display: block;
    background-color: #fff;
    -webkit-mask-image: var(--fieldset-links-summary-mask);
    mask-image: var(--fieldset-links-summary-mask);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
}

.fieldset-links-summary-text {
    font-size: 13px;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.fieldset-links-summary-text--prompt {
    color: rgba(255, 255, 255, 0.6);
    font-style: italic;
}

/* Item Pricing summary — the doorway to the Item Pricing Modal. Same
   summary-button pattern as the amenities summary above (row, filled
   text, italic empty-state prompt); the filled state is a text line
   ("item name — price") rather than icon tiles. */
/* Grid mirror of .fieldset-sessions-tp-legend-row: name is the only
   flexible cell (minmax(0,1fr) lets a Supercalifragilistic item name
   ellipsize); price / variants / age / promo hug the right edge in the
   same order the ticket legend uses, same 36px height and 10px gaps. */
.fieldset-itempricing-summary-row {
    display: grid;
    /* Leading auto column = the fieldset icon (fieldset-sessions-summary-icon). */
    grid-template-columns: auto minmax(0, 1fr) auto auto auto auto;
    column-gap: 10px;
    align-items: center;
    height: 36px;
    padding: 0 10px;
    text-align: left;
    box-sizing: border-box;
    width: 100%;
}

.fieldset-itempricing-summary-name {
    font-size: 13px;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.fieldset-itempricing-summary-price,
.fieldset-itempricing-summary-variants {
    font-size: 13px;
    color: #fff;
    white-space: nowrap;
}

.fieldset-itempricing-summary-text {
    font-size: 13px;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.fieldset-itempricing-summary-text--prompt {
    /* Column 1 is the fieldset icon; the prompt fills the rest. */
    grid-column: 2 / -1;
    color: rgba(255, 255, 255, 0.6);
    font-style: italic;
}

/* Twin of .fieldset-sessions-tp-legend-age-icon (20px, the badge's height). */
.fieldset-itempricing-summary-age-icon {
    width: auto;
    height: 20px;
    object-fit: contain;
}

/* Twin of .fieldset-sessions-tp-legend-promo-badge, minus the grid
   stretch (this summary is a flex row, the badge hugs its code). */
.fieldset-itempricing-summary-promo-badge {
    display: inline-flex;
    align-items: center;
    height: 20px;
    padding: 2px 8px;
    background: var(--green-600);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    border-radius: 4px;
    letter-spacing: 0.02em;
    white-space: nowrap;
    box-sizing: border-box;
}

/* ============================================================================
   TIMELINES FIELDSET (Stage 1: index page + pane navigation)
   Copies the sessions fieldset row metrics (36px rows, 10px padding).
   ============================================================================ */

.fieldset-timelines-index-container > * {
    margin-bottom: 10px;
}
.fieldset-timelines-index-container > *:last-child {
    margin-bottom: 0;
}

/* Group divider row: name input + optional delete button. */
.fieldset-timelines-timeline-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

/* DATES ROW (operator 2026-09-19): the timeline's row stands under its own
   "Timeline Dates" label as the ordinary 36px summary button — the calendar
   proved too tall for a phone, so the dates keep their own page and this is
   simply the way in. It wears the main form's calendar badge, so it lays out
   as a ROW (icon, then text) rather than the index button's column, while
   the 36px drag strip on the right is untouched. */
/* The row wears the main form's own summary-row class, so the badge, the
   left-aligned name and the right-aligned range come from the code that
   already draws it on the front end. The only thing it must add back is the
   drag strip: .fieldset-timelines-index-drag is absolutely positioned, so
   without a positioned parent and its 36px of clearance it escaped to the
   corner of the X (seen on staging 2026-09-19). */
.fieldset-timelines-timeline-row--datesbox .fieldset-timelines-summary-row {
    position: relative;
    padding-right: 36px;
}

/* Labeled group container (operator 2026-08-27): the location-container
   anatomy — numbered header band over a bordered content box (geometry
   from .member-postform-location-header, formbuilder.css ~1587; chrome
   from the container-class-2 header/content pair). */
.fieldset-timelines-timeline-container {
    margin-bottom: 10px;
}

.fieldset-timelines-timeline-header {
    display: flex;
    align-items: center;
    /* Icon · Timeline N · date range · controls, 10px apart like the summary
       row (.fieldset-sessions-summary-row); the range fills the middle, so
       the controls stay hard right. The bar is also the measuring container
       for the weekday drop below (the session-menu doorway's approach,
       post.css .post-sessionmenu-button). */
    gap: 10px;
    container-type: inline-size;
    height: 36px;
    padding: 0 0 0 10px;
    font-size: 14px;
    box-sizing: border-box;
}

/* accordion-class-3 body: invisible and full width, so the contents run to
   the sides (operator 2026-09-19). Only the top gap survives. */
.fieldset-timelines-timeline-content {
    padding: 10px 0 0;
}

.fieldset-timelines-timeline-content > * {
    margin-bottom: 10px;
}

.fieldset-timelines-timeline-content > .fieldset-sublabel {
    /* Follows the form-wide 10px sublabel gap (operator 2026-09-08). */
    margin-bottom: 10px;
}

.fieldset-timelines-timeline-content .fieldset-timelines-timeline-input {
    width: 100%;
    box-sizing: border-box;
}

/* (Header +/- wear the ticket-pricing group button classes + the
   location-header controls wrapper — no timelines-own styling needed;
   the AddRemoveComponent first pass retired 2026-08-27.) */

/* Numbered line under the band — carries the GROUP completeness dot. */
.fieldset-timelines-timeline-number {
    font-size: 14px;
    /* Flex line so the completeness dot centers vertically against the
       text (the bare-baseline dot sat off-center; operator 2026-08-27). */
    display: flex;
    align-items: center;
}

.fieldset-timelines-timeline-input {
    flex: 1;
    height: 36px;
    padding: 0 10px; /* system input padding (fieldset-input pattern) */
    box-sizing: border-box;
}

/* (Bespoke img sizing rule removed 2026-08-28 — the X is a
   fieldset-timelines-icon mask glyph now, sized by its shared class like
   every other icon in the fieldset.) */

/* System icon glyphs (mask pattern copied from .admin-moderation-item-btn-icon,
   admin.css) — perfectly centered by the flex button that holds them. */
.fieldset-timelines-icon {
    display: inline-block; /* same as .component-addremove-icon — without it the inline span collapses and the mask paints tiny */
    width: 18px;
    height: 18px;
    background-color: currentColor;
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
}

/* ── DATE SPAN LINK TOOLS (approved vocabulary 2026-08-27). The 36px link
   button rides immediately left of the time input (reserved slot when any
   date in the list is linkable — alignment law); mask glyph from the
   admin-set --ui-icon-link, same mask pattern as .fieldset-timelines-icon
   below. */
.fieldset-timelines-datespan-link {
    flex: 0 0 36px;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    /* class-2's 0 12px padding crushed the glyph to ~12px of content
       width (operator catch 2026-08-27) — square icon buttons carry none. */
    padding: 0;
}
.fieldset-timelines-datespan-link::before {
    content: '';
    display: inline-block;
    /* Back to the house 18px (operator 2026-08-27 ~21:34) — the tiny
       rendering was the class-2 padding crush, not the glyph size. */
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    background-color: currentColor;
    -webkit-mask: var(--ui-icon-link) center / contain no-repeat;
    mask: var(--ui-icon-link) center / contain no-repeat;
}
/* Linked = WHITE icon inside a BLUE border (operator 2026-09-20, the span
   row's twin): the icon keeps button-class-2's own white, only the border
   turns blue. Dark theme only in effect — the light button-class-2 twin
   (themes.css ~180) outranks this rule, so light shows its usual idle face. */
.fieldset-timelines-datespan-link--linked {
    border-color: var(--blue-500);
}
/* Linked state wears the UNLINK icon (admin-set icon_unlink). */
.fieldset-timelines-datespan-link--linked::before {
    -webkit-mask-image: var(--ui-icon-unlink);
    mask-image: var(--ui-icon-unlink);
}
/* The 'Date Span · N Dates' row — the hidden dates' representation while
   collapsed; the arrow flips on expand (mask pattern from the dropdown
   arrows, base.css ~1987). */
/* OPERATOR DESIGN 2026-08-28 ~00:19 — the shared TEXT SKELETON for both
   forms of the span row: the pure-text label (empty spans) and the
   accordion-class-5 header (real spans). Same box metrics either way so
   the grid never shifts. */
.fieldset-timelines-datespan-row {
    /* Left-aligned (operator 2026-08-28); arrow clearance right. */
    text-align: left;
    padding: 0 36px 0 10px;
    width: 100%;
    height: 36px;
    box-sizing: border-box;
    font-size: 13px;
    position: relative; /* anchors the corner arrow */
    /* Overflow safety: truncate the phrase, never drop data silently —
       the date-label ellipsis law (operator 2026-08-28). */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: block;
    line-height: 34px;
    /* Weight contrast only — heavy times against light dates. */
    font-weight: 300;
}
/* Empty two-date spans wear the SAME class-5 chrome (operator 2026-08-28
   ~00:24, supersedes the invisible-skeleton form) — just inert: no
   aria-expanded means no arrow (the arrow rule below) and no pointer. */
.fieldset-timelines-datespan-row:not([aria-expanded]) {
    cursor: default;
}
/* The inert form never hovers — a hover state on a non-clickable lies. */
.fieldset-timelines-datespan-row:not([aria-expanded]):hover {
    background: var(--accordion-header-bg);
    border-color: var(--accordion-header-border);
}
/* Real spans: accordion-class-5 (the button-matching accordion) with the
   date span's dark-only identity — WHITE contents inside a BLUE border
   (operator 2026-09-20: the blue writing and arrow read badly, and went
   murky over the hover grey). The writing and the arrow (currentColor) are
   class-5's own white; only the border is set here. Light theme keeps
   class-5's light button mirror because the light :root twin outranks this. */
.fieldset-timelines-datespan-accordion {
    --accordion-header-border: var(--blue-500);
}
/* Open span: the header owns the gap down to its first date row — the list's
   own 8px table rhythm (the rows and the span itself sit 8px apart). It was
   0: the class-5 body carries no padding. */
.fieldset-timelines-datespan-accordion.accordion-class-5--open .fieldset-timelines-datespan-row {
    margin-bottom: 8px;
}
.fieldset-timelines-datespan-row-time {
    font-weight: 700;
}
/* Corner arrow — the accordion pattern (.fieldset-timelines-pattern-expand
   above): right-edge position, 16px glyph. */
.fieldset-timelines-datespan-row[aria-expanded]::after {
    content: '';
    position: absolute;
    top: 50%;
    right: 10px;
    width: 16px;
    height: 16px;
    margin-top: -8px;
    background-color: currentColor;
    -webkit-mask: var(--ui-icon-arrow-down) center / 16px 16px no-repeat;
    mask: var(--ui-icon-arrow-down) center / 16px 16px no-repeat;
}
.fieldset-timelines-datespan-row[aria-expanded="true"]::after {
    transform: rotate(180deg);
}
/* Date wheels read at the list's body size — the time wheels' 22px is
   sized for two digits, not 'Wed 10 Feb, 2027' (operator 2026-08-27). */
.fieldset-timelines-datespan-popup .fieldset-sessions-timepickermodal-wheel-item {
    font-size: 13px;
}
/* Grid lock (operator 2026-08-27 ~21:47): chips and buttons are fixed;
   the DATE is the flexible column and truncates. */
.fieldset-timelines-daytimerange-row .fieldset-sessions-session-field-label {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: block;
    line-height: 36px;
}
/* Date squeeze (operator 2026-08-28, BREAKPOINT REFERENCE in base.css):
   below 410px the widest year-bearing date cannot fit the label column,
   so year-bearing dates drop their weekday prefix — never an ellipsis. */
@media (max-width: 410px) {
    .fieldset-timelines-daytimerange-weekday {
        display: none;
    }
}
/* Breathing room inside the time chips (operator 2026-08-27). */
.fieldset-timelines-timerange-input {
    padding: 0 8px;
}

.fieldset-timelines-icon--trash {
    -webkit-mask-image: var(--ui-icon-trash);
    mask-image: var(--ui-icon-trash);
}

.fieldset-timelines-icon--clear {
    -webkit-mask-image: var(--ui-icon-clear);
    mask-image: var(--ui-icon-clear);
}

.fieldset-timelines-icon--edit {
    -webkit-mask-image: var(--ui-icon-edit);
    mask-image: var(--ui-icon-edit);
}

.fieldset-timelines-icon--left {
    -webkit-mask-image: var(--ui-icon-left);
    mask-image: var(--ui-icon-left);
}

.fieldset-timelines-icon--right {
    -webkit-mask-image: var(--ui-icon-right);
    mask-image: var(--ui-icon-right);
}

/* Drag handle strip + icon — copied from the formbuilder accordion handle
   (formbuilder.css 133-152), icon filled with currentColor (the
   fieldset-timelines-icon family's theme-safe fill) instead of raw white. */
.fieldset-timelines-index-drag {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: grab;
}

.fieldset-timelines-index-drag-icon {
    width: 16px;
    height: 16px;
    background-color: currentColor;
    -webkit-mask-image: var(--ui-icon-drag-handle);
    mask-image: var(--ui-icon-drag-handle);
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
}

.fieldset-timelines-timeline-row.dragging {
    opacity: 0.5;
}

/* One 36px button per timeline on the index page (twin of
   .fieldset-sessions-summary-row). */
.fieldset-timelines-index-button {
    /* Full name, never truncated (operator 2026-08-27): the button is a
       COLUMN that grows as many lines as the name needs — 36 stays the
       minimum, not a ceiling (the bracket-container height law) — and the
       date range gets its own dedicated line. The right 36px is the
       dedicated DRAG HANDLE strip (operator 2026-08-28). */
    position: relative;
    padding-right: 36px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    min-height: 36px;
    height: auto;
    padding: 8px 10px;
    gap: 3px;
    text-align: left;
    box-sizing: border-box;
    /* Flexible width, never wider than the row: width:100% + min-width:auto
       let a long name shove the delete X out of the row (bug 2026-08-26 —
       same min-width:0 guarantee the summary-name span carries). */
    flex: 1 1 auto;
    min-width: 0;
    font-size: 13px;
}

.fieldset-timelines-index-button .fieldset-timelines-summary-name {
    flex: 0 0 auto;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
}

.fieldset-timelines-index-button .fieldset-timelines-summary-range {
    flex: 0 0 auto;
    text-align: left;
}

.fieldset-timelines-index-button--unnamed {
    font-style: italic;
}

/* Pane hosts the timelines time picker overlay (twin of the sessions
   picker mounting on the SideModal container). */
.fieldset-timelines-pane-container {
    position: relative;
}

/* Mode row: the four Timeline Tools. */
.fieldset-timelines-tools-row {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 36px;
    margin-bottom: 10px;
}

.fieldset-timelines-tool {
    flex: 1;
    height: 36px;
    font-size: 13px;
}

/* Active state = the standard tab mechanic (operator 2026-08-26): the tool,
   weekday, and loop buttons are button-class-2 and light up via
   aria-selected, exactly like the panel tab bars — no custom active class. */
/* Resting gray border + blue focus glow — copied from the sessions calendar
   (.fieldset-sessions-calendar-container, above). */
/* (Timeline editor modal skin REMOVED 2026-09-20: it hid the modal header,
   the mode band and the fieldset label whenever the modal opened with a
   timeline's editor showing — a three-page rule that made arriving on an open
   timeline lose the header. One page: the header always stays.) */

/* HIDDEN pending a header redesign (operator 2026-08-27 — "might, might
   not"): the cloned Timelines label. The page label (Timeline Times above
   the times grid) is exempt. The nav row and the pane's own name field that
   this rule also served were removed 2026-09-20. */
.fieldset-timelines-pane-container .fieldset-label:not(.fieldset-timelines-pagelabel) {
    display: none;
}

/* Date-mode calendar rides sticky at the very top of the editor page
   (operator 2026-08-27) — same anatomy as the time-mode mini below. Scoped
   to the pane so the span builder's in-form calendar stays in flow. */
/* LOCKED, not sticky (operator correction 2026-08-27: sticky bounces on
   iPhone rubber-band) — the calendar is a fixed member of the editor
   column and the REST of the editor scrolls beneath it, copying the
   reader-side locked-calendar anatomy (.post-timeline-options--slideinmodal
   .post-timeline-pane, components.css ~4840). */
/* LOCKED-LAYOUT ROLLED BACK (operator 2026-08-27 ~01:03: the flex/overflow
   chain broke the iPhone header/footer viewport lock — bottom shrouded by
   the address bar, flicking). The modal body scrolls again as before; the
   pane-scroll wrapper stays in the DOM but is layout-invisible. The
   locked-calendar goal needs a fresh design that never touches the modal
   body's overflow. */
.fieldset-timelines-pane-scroll {
    display: contents;
}

/* Times box (operator 2026-09-19): the time interface stands in the dates
   area's exact footprint and scrolls inside itself; its border and the drag
   handle beneath it belong to the .component-textarearesize wrapper. That
   wrapper stands where the calendar stood (last in the pane since the
   2026-09-22 20:50 order). A clean 20px gap beneath it (operator 2026-09-22,
   replacing the divider line of twenty minutes earlier) parts each timeline
   from the next; the same gap in both modes, so the bars beneath never move. */
.fieldset-timelines-pane-scroll > .component-textarearesize {
    margin-bottom: 20px;
}

.fieldset-timelines-timesbox {
    overflow-y: auto;
    /* No `contain` here (operator 2026-09-19): the box sits inside the form,
       so once its list reaches an end the wheel must carry on scrolling the
       modal instead of stopping dead. */
    scrollbar-width: thin;
    padding: 10px 10px 0;
}

/* (Sticky-head calendar override REMOVED 2026-08-27 ~17:42 — the calendar
   left the sticky head and scrolls in the page flow again, so the base
   full-bleed rule below owns it; the time-mode mini keeps its own rules.) */

/* (Name-field delete row removed 2026-08-27 ~18:24 — operator: the input
   is full width, deletion is the index X only.) */

.fieldset-timelines-calendar-container {
    margin-bottom: 10px;
    /* FRAMED (operator 2026-09-20 — supersedes the 2026-08-26 edge-to-edge
       ruling, written when the calendar was a full page): inside the
       accordion it wears the base .calendar-container frame (components.css
       ~260: 1px border, 8px radius, clipped corners), matching the Time
       Blocks box that takes its place in time mode. Only the resting colour
       is set here; the focus blue is the --focused rule below, the light
       twin is in themes.css. The post timelines menu has its own mount and
       stays edge to edge. Ground matches the bracket containers
       (button-class-4, base.css ~798). */
    border-color: #333;
    background: rgba(0, 0, 0, 0.35);
}

/* The picker names its ground, so its dates wear THE DATE OUTLINE (base.css)
   like the reader menus' and the coupon picker's — the month name is cut back
   around every number. A painted circle covers its own outline. */
.fieldset-timelines-calendar-container .ghostcalendar-grid .ghostcalendar-day {
    --calendardate-ground: var(--calendardate-picker-ground);
}

/* NO BLUE WEEKDAY BAND HERE (operator 2026-09-22, "we're gonna have to make this
   clearer" — the band sat between the blue timeline bars and the blue active
   buttons; reversing his 2026-09-20 "the timelines calendar would look better
   with the blue as well"). The timelines picker keeps the ghost calendar's own
   weekday line; the coupon, filter and sessions pickers keep their band. */

/* The ghost calendar's own blue line under itself (ghostcalendar.css
   .ghostcalendar-wrapper) would double against the frame's bottom edge. */
.fieldset-timelines-calendar-container .ghostcalendar-wrapper {
    border-bottom: none;
}

.fieldset-timelines-calendar-container--focused {
    border-color: var(--blue-500);
}

/* THE CALENDAR DRAGS IN HEIGHT (operator 2026-09-22): wrapped in the same
   .component-textarearesize as the Time Blocks box, so the wrapper draws the
   frame and the handle; the container's own frame and gap stand down (the
   wrapper keeps the 10px gap). Focus blue moves to the wrapper. Two rows at
   least: the weekday band and 2 x 36. */
.component-textarearesize > .fieldset-timelines-calendar-container {
    border: none;
    border-radius: 0;
    margin-bottom: 0;
    min-height: 108px;
}

/* ...but not while the weekday popup stands over it (operator 2026-09-22): the
   focus blue belongs to the popup then, the blurred calendar goes plain. */
.component-textarearesize:has(> .fieldset-timelines-calendar-container--focused:not(.fieldset-timelines-calendar-container--loopdays)) {
    border-color: var(--blue-500);
}

/* (The 2026-08-26 boxed time-mode scroll anatomy is GONE — operator: the
   whole point is maximizing screen space. The MODAL BODY scrolls as one,
   the mini calendar is the sticky. Slack itself was later discarded the
   same day; the slot wrappers remain as inert structure.) */

/* The slot wrappers are layout-invisible (display: contents): the bracket
   containers keep their own margins exactly as before the slots existed —
   the wrapper swallowed the 3px rhythm otherwise (operator catch). */
.fieldset-timelines-bracket-slot {
    display: contents;
}

/* ── TIME MODE (operator 2026-08-26) ─────────────────────────────────────
   The calendar shrinks to a 100px sticky mini mirror — EDGE TO EDGE like
   the modal header (stickies must own the full width or they look broken),
   aspect ratio kept via zoom, dates still painted/veiled accurately.
   Clicking it returns to date mode. Local z 2 (see base.css Z-INDEX
   REFERENCE) keeps it over the scrolling brackets inside the pane. */
.fieldset-timelines-pane-container {
    position: relative;
}
.fieldset-timelines-calendar-container--mini {
    /* The base calendar-container is width:100%, which ignores the -10px
       margins — the strip fell 20px short on the right. Explicitly span
       the padding box (operator catch 2026-08-26). */
    width: calc(100% + 20px);
    /* Sticky REMOVED (operator 2026-08-27 ~18:26): the nav row is the ONLY
       sticky thing in the editor — the time-mode mini scrolls away with
       everything else. */
    /* Natural size (operator round 3, 2026-08-26): the sticky uses the
       cute calendar ITSELF — the zoomed strip of the old horizontal
       layout is retired ("the other one doesn't even make sense anymore").
       Already edge-to-edge from the base rule above. */
    height: auto;
    overflow: hidden;
    margin: 0 -10px 10px;
    border-radius: 0;
    border-left: none;
    border-right: none;
    cursor: pointer;
    /* Ground matches the base timelines calendar (bracket-container tone);
       sticky needs an OPAQUE ground so brackets never show through — the
       0.35 alpha over the panel's #111 resolves to ~#0b0b0b (operator
       uniform-ground rule 2026-08-26). Light twin in themes.css. */
    background: #0b0b0b;
}
/* The mini's scrollbar was zoomed tiny while the zoom sat on the scroll
   element; unzoomed it became a full-size bar (a giant dark band in light
   theme). The 100px mirror hides its bar — wheel, drag, and touch still
   scroll (operator 2026-08-26). */
.fieldset-timelines-calendar-container--mini .calendar-scroll {
    scrollbar-width: none;
}
.fieldset-timelines-calendar-container--mini .calendar-scroll::-webkit-scrollbar {
    display: none;
}

/* Expanded bracket editor (time mode): view switch tabs share the tab-bar
   anatomy (member.css .member-tab-bar — equal-fill class-2 buttons). */
.fieldset-timelines-bracketeditor {
    margin-bottom: 12px;
    /* The bracket skin, expanded — not a clickable summary anymore: no
       whole-container hover tint (pins class-2's IDLE colors over its hover
       rule; light twin in themes.css). */
    cursor: default;
}
.fieldset-timelines-bracketeditor.button-class-2:hover {
    background: rgba(0, 0, 0, 0.1);
    border-color: rgba(255, 255, 255, 0.18);
}
/* Line 1 grid grows to the close button's height so the X never overlaps
   the view row beneath it. */
.fieldset-timelines-bracketeditor .fieldset-timelines-pattern-grid {
    min-height: 36px;
}
/* 10px under the header grid line before the view row (the view row's own
   margin gives the next 10). */
.fieldset-timelines-bracketeditor-content {
    padding-top: 10px;
}
/* Corner EXPAND ARROW (operator 2026-08-26) — identical spot on summaries
   and the expanded editor (the accordion trick); geometry = the old pencil
   corner anatomy. Arrow glyph = the shared menu arrow (--ui-icon-arrow-down,
   base.css ~1982), flipped 180 when open. */
.fieldset-timelines-pattern-expand {
    position: absolute;
    top: 8px;
    right: 10px;
    width: 36px;
    height: 36px;
    /* Decoration only — the header/summary is the click target. */
    pointer-events: none;
    background: currentColor;
    -webkit-mask: var(--ui-icon-arrow-down) center / 16px 16px no-repeat;
    mask: var(--ui-icon-arrow-down) center / 16px 16px no-repeat;
}
.fieldset-timelines-pattern-expand-arrow--open {
    transform: rotate(180deg);
}
/* The editor's header line is the collapse target — a normal accordion
   header gesture. */
.fieldset-timelines-bracketeditor-headerline {
    cursor: pointer;
}
/* Accordion summaries wear button-class-2 (operator 2026-08-26) — the same
   base class and colors as the Weekdays/Date List tabs; no custom skin. */
.fieldset-timelines-bracketeditor-viewrow {
    display: flex;
    gap: 6px;
    margin-bottom: 10px;
}
.fieldset-timelines-bracketeditor-view {
    flex: 1;
    height: 36px;
}

/* Couple row header: the summary button owns the width; the + / − pair
   rides embedded on its right (the links-row anatomy, fieldsets.js ~1991). */
.fieldset-timelines-daytimerange-headerrow {
    display: flex;
    align-items: center;
    gap: 6px;
}
.fieldset-timelines-daytimerange-headerrow .fieldset-timelines-daytimerange-summary {
    flex: 1;
    min-width: 0;
    /* width:100% (the base rule) fights the flex row and shoves the +/−
       pair — auto lets flex own the width (operator catch 2026-08-26). */
    width: auto;
}

/* ── Bracket pattern containers (recognizer pass 1, operator 2026-08-25):
   screenlayer-row geometry — min 36px tap surface, 3px gaps, borderless.
   Loop = title + weekday letter strip; Range = one line; Random = title +
   compressed date stream in the secondary text color. */
.fieldset-timelines-pattern-list {
    margin-bottom: 10px;
}

/* BRACKETS BURIED (operator 2026-08-27): the recognizer keeps running
   behind the scenes — storage, counters, splits all live — but bracket
   summaries and the bracket list NEVER paint on the date editor. The
   phone-friendly editor is dates only; times arrive via the coming
   mode-switch button. Time mode keeps its list for now (today's only
   path to times). */
.fieldset-timelines-pane-container:not(.fieldset-timelines-pane-container--timemode) .fieldset-timelines-pattern-list,
.fieldset-timelines-pane-container:not(.fieldset-timelines-pane-container--timemode) .fieldset-timelines-bracket-list {
    display: none;
}

/* THREE BUTTONS under the calendar (operator 2026-08-27): Edit Dates /
   Edit Times / Index — equal fill, phone-first big writing, tab mechanic
   actives via aria-selected (button-class-2). */
/* THE EDITOR HEADER (operator 2026-08-27 ~18:28, supersedes every sticky
   design): NO stickies — the nav row is mounted as a true header row of
   the modal CONTAINER, a sibling ABOVE .component-sidemodal-body (the
   scroller), exactly the component-sidemodal-header anatomy. It is simply
   not part of the scrollable area. */
.fieldset-timelines-stickyhead {
    width: 100%;
    box-sizing: border-box;
    background: #0b0b0b;
}

.fieldset-timelines-modeswitch-row {
    display: flex;
    gap: 10px;
    /* Its own line under the undo row (operator 2026-09-19); three thirds
       since 2026-09-22 (Dates | Time Blocks | Close). The old inset and
       separator belonged to the sticky head this row used to live in. */
    box-sizing: border-box;
    margin-bottom: 10px;
}

/* Operator 2026-08-27 vertical rhythm: line -> 10px -> controls -> 30px ->
   instruction -> 30px -> tools (a roomy instruction zone for verbose
   guidance). Pane-scoped so the span builder keeps its own spacing. */
/* Rhythm (operator 2026-08-27 ~02:45): controls -> 10px -> tools ->
   instruction zone beneath. */
.fieldset-timelines-pane-container .fieldset-timelines-controls-row {
    margin-bottom: 10px;
}

.fieldset-timelines-pane-container .fieldset-timelines-tools-row {
    /* 10px under the tool bar (operator 2026-09-19, superseding the 30px of
       the full-page editor). This is the rule that governs — the base one
       below never gets a look in. */
    margin-bottom: 10px;
}

.fieldset-timelines-pane-container .fieldset-timelines-tools-instruction-row {
    /* 10px under the instruction (operator 2026-09-19, superseding the 16px
       paragraph break that fed the deleted tool legend). */
    margin-bottom: 10px;
}

/* Time-mode instruction breathing (operator 2026-08-27): 30px each side,
   with the reassurance paragraph a break below. Light twin in themes.css. */
.fieldset-timelines-pane-container--timemode .fieldset-timelines-tools-instruction-row {
    padding: 0 30px;
    margin-bottom: 16px;
}

/* 36px system size (operator ruling 2026-08-27 after weighing the 44pt
   Apple target: the whole site is built on 36, and dense software can't
   afford app sizes — "continue with 36 and keep moving"). Flex fill,
   10px gaps from the row. */
.fieldset-timelines-modeswitch {
    flex: 1 1 0;
    min-width: 0;
    height: 36px;
    position: relative;
}

/* Index caret (operator 2026-08-27): the word stays CENTERED as if no
   arrow existed; the caret floats halfway between the word's end and the
   button edge. */
.fieldset-timelines-modeswitch .component-sidemodal-button-glyph {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    right: 10px;
    margin-left: 0;
    vertical-align: baseline;
}

.fieldset-timelines-pattern-container {
    display: block;
    width: 100%;
    height: auto;
    min-height: 36px;
    padding: 8px 10px;
    /* 6px under each bracket (operator 2026-08-26, was the 3px clump). */
    margin-bottom: 6px;
    text-align: left;
    line-height: 1.4;
    /* Anchor for the corner edit button (operator 2026-08-26). */
    position: relative;
}

/* (Corner pencil edit button removed 2026-08-26 — the bracket click opens
   the inline editor; only the editor's own close X uses the corner slot.) */

/* Every container is the sole child of its display:contents slot, so a bare
   :last-child matched ALL of them and zeroed every gap (the missing-margin
   bug, operator catch 2026-08-26) — the LAST SLOT's container is the real
   last row. */
.fieldset-timelines-bracket-slot:last-child .fieldset-timelines-pattern-container {
    margin-bottom: 0;
}

/* Line 1 grid: type | date count | date range — fixed columns so every
   bracket lines up; the range cell truncates on narrow screens. */
.fieldset-timelines-pattern-grid {
    display: flex;
    align-items: center;
    gap: 8px;
    /* Clear the corner edit button (36px + 10px padding). */
    padding-right: 46px;
    font-size: 13px;
    /* Title treatment (operator 2026-08-25): semibold, same as parent
       fieldset labels — the weight difference separates the title from the
       gray content rows without spending vertical space. */
    font-weight: 600;
    margin-bottom: 6px; /* label-to-element rhythm (6px rule) */
}

.fieldset-timelines-pattern-type {
    flex: 0 0 52px;
}

.fieldset-timelines-pattern-count {
    flex: 0 0 64px;
}

.fieldset-timelines-pattern-range {
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Gray time rows (the day-of-week / per-date + time grid — secondary color,
   not the white of line 1; operator 2026-08-25). */
.fieldset-timelines-pattern-times {
    font-size: 12px;
    color: var(--text-secondary);
}

.fieldset-timelines-pattern-time-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Missing-time red dots breathe like the header's "Timelines ●" dot
   (operator 2026-08-27): an explicit 8px inset from the times — the row's
   own 8px rhythm — instead of hugging the digits. */
.fieldset-timelines-pattern-time-row .fieldset-label-required,
.fieldset-timelines-daytimerange-row .fieldset-label-required {
    margin-left: 8px;
}

.fieldset-timelines-pattern-time-label {
    flex: 0 0 124px;
}

/* Start / dash / end are fixed columns — blank (--:--) and filled times
   occupy identical space so every colon and dash aligns down the page. */
/* Full time sub-grid (operator 2026-08-25): hour, colon, minute, dash, hour,
   colon, minute — every cell fixed and centered, so all colons and dashes
   align exactly down the page, blank (--) and filled alike. The grid starts
   on the title grid's range column (label 124 + 8 gap = 132px). */
.fieldset-timelines-pattern-timegrid {
    display: flex;
    align-items: center;
    font-variant-numeric: tabular-nums;
}

.fieldset-timelines-pattern-time-hour,
.fieldset-timelines-pattern-time-minute {
    flex: 0 0 2ch;
    text-align: center;
}

.fieldset-timelines-pattern-time-colon {
    flex: 0 0 auto;
}

.fieldset-timelines-pattern-time-dash {
    flex: 0 0 auto;
    margin: 0 6px;
}

/* ── Bracket time rows (the popup shell died 2026-08-26 — these classes now
   serve the inline bracket editor only). */
.fieldset-timelines-daytimerange-instruction {
    /* Popup-era padding dropped with the popup; the container pads the
       sides, the margin gives the 10px rhythm below. */
    padding: 0;
    margin-bottom: 10px;
}

/* Popup-era padding + internal scroll caps removed 2026-08-26 with the
   popup itself — the editor container supplies the 10px sides; anything
   more double-inset the accordions (operator catch). */
.fieldset-timelines-daytimerange-rows {
    padding: 0;
}

/* The editor wrapper is button-class-2 (font-weight 600) — the session rows
   inside must read EXACTLY like the sessions modal's (operator 2026-08-26),
   so the rows reset to the normal weight the sessions container has. */
.fieldset-timelines-bracketeditor .fieldset-sessions-session-row {
    font-weight: 400;
}

/* (OVERNIGHT skins DELETED 2026-08-27 ~19:32 — midnight law outlawed
   end-below-start couples; moons, blue chips, and the Overnight word all
   retired.) */

/* Warning line under the popup wheels (operator 2026-08-27): equal times,
   past-midnight end, and crossover messages — danger color (the
   required-dot red). Light twin in themes.css. */
/* THE RED READOUT (operator 2026-09-23): the wheel item under the band wears
   --selected (timelinesBuildWheelColumn); while the picker's pair overlaps a
   block on that date the pair wears --conflict, and those numbers go the
   conflict red. Light twin in themes.css. */
.fieldset-timelines-timepickermodal-dualpair--conflict .fieldset-sessions-timepickermodal-wheel-item--selected {
    color: #f87171;
}

.fieldset-timelines-conflict-word {
    text-align: center;
    font-size: 13px;
    color: #f87171;
    margin-bottom: 10px;
    padding: 0 10px; /* system padding — all warnings share this class (operator 2026-08-27) */
}

/* Faint divider between bracket regions in the flat list (operator
   2026-08-26 — informative, never obstructive). Light twin in themes.css. */
.fieldset-timelines-flatlist-divider {
    height: 1px;
    background: rgba(255, 255, 255, 0.1);
    margin: 8px 0;
}
.fieldset-timelines-daytimerange-row .fieldset-sessions-session-field-time {
    position: relative;
}

/* Time RANGE chip (sessions-row anatomy, operator 2026-08-26): the sessions
   time box is 55px for one time; the range couple needs roughly double —
   same container-query auto-fit rides in from the sessions classes. */
.fieldset-timelines-daytimerange-row .fieldset-sessions-session-field-time {
    flex: 0 0 110px;
}

.fieldset-timelines-daytimerange-row {
    /* 6px — matches the header row's horizontal gap (operator 2026-08-26). */
    margin-bottom: 6px;
}

.fieldset-timelines-daytimerange-summary {
    display: block;
    width: 100%;
    min-height: 36px;
    padding: 8px 10px;
    text-align: left;
    cursor: pointer;
    box-sizing: border-box;
}
/* The editor's rows are accordion-class-5 — the summary button IS the
   .accordion-header (operator 2026-08-26): its box stops before the +/−
   pair, which rides beside it in the flex row. */

.fieldset-timelines-daytimerange-summary .fieldset-timelines-pattern-time-row {
    font-size: 12px;
}

.fieldset-timelines-daytimerange-save {
    display: block;
    width: calc(100% - 20px);
    margin: 10px;
}

.fieldset-timelines-bracket-list {
    margin-bottom: 10px;
}

/* Calendar veil (veil law — same visual family as the loading veil, never
   gray-out): ineligible dates dim and stop taking clicks while a guided
   loop flow runs. */
/* VEIL OFF for now (operator 2026-08-27: the old lip-system veil is broken
   against the new editor — see the screen first, appearances later). The
   class still blocks clicks; only the dimming is gone. */
.ghostcalendar-day.ghostcalendar-day--veiled {
    pointer-events: none;
    opacity: 0.5;
}

/* THE PICKER'S DATE COLOURS ARE NOT IN THIS FILE (operator 2026-09-20). Every
   colour a date in this calendar can wear - Idle, Active, the tool hovers, the
   paint hovers, and the Past twin of each (the grey zone) - is a term of THE
   CALENDAR DATE REGISTRY: values in base.css, one rule per term in
   components.css. This file owns the tools, the gestures and the classes they
   stamp; it never gives a date a background or a color. */

.fieldset-timelines-calendar-container .ghostcalendar-day.empty {
    cursor: default;
}

/* Instruction line under the tool row, above the calendar (operator
   2026-08-26 order: tools, instruction, calendar) — what the next tap will
   do; the loop flow speaks through it too (no override banner). */
.fieldset-timelines-tools-instruction-row {
    /* Prominent, never a fine-print disclaimer (operator 2026-08-26):
       big text, centered so surrounding white space frames it, wraps to
       two lines if needed — this band scrolls away, so it costs no
       permanent screen space. */
    /* 13px (operator 2026-09-22, down from the 16px of 2026-08-26): the form's
       own text size, so the sentence can live on a narrower line. */
    font-size: 13px;
    /* WHOLE PIXELS (operator 2026-09-19): 13 x 1.3 = 16.9px, and that 0.9
       would push everything below it onto fractional y positions — which
       made the month divider's 1px line straddle two device rows and read as
       lumpy. 17px keeps every row on a whole pixel. */
    line-height: 17px;
    text-align: center;
    margin-bottom: 10px;
}

/* (Tool-name prefix removed 2026-08-27 — .fieldset-timelines-tools-
   instruction-tool retired with it.) */

/* Weekday step (operator 2026-09-22, the rebuilt loop): the calendar blurs
   behind the loop popup and takes no taps — the popup is the whole step. A
   tap on it is a click-away, which cancels. (The 2026-08-27 scroll freeze
   for the old on-calendar weekday step is retired.) */
.fieldset-timelines-calendar-container--loopdays {
    filter: blur(4px);
    pointer-events: none;
}

/* Tool cursor shapes REMOVED (operator 2026-08-25): the hover appearances
   (C-cups, red border) carry the tool identity now — the cursor stays
   default for every tool. The --cursor-* container classes remain as the
   active-tool hooks for the hover rules above. */

/* Loop controls POPUP (operator 2026-08-26): the time picker card look, full
   pane width; since 2026-09-22 it sits OVER the calendar, centred on it (JS
   sets top), the calendar blurred behind. Click-away cancels the flow. */
.fieldset-timelines-loopdays {
    /* The focus blue (operator 2026-09-22): while the popup stands over the
       blurred calendar it is the thing in focus; the calendar's own blue
       stands down (the :not(--loopdays) on its focus rule above). */
    border: 1px solid var(--blue-500);
    position: absolute;
    left: 0;
    right: 0;
    width: auto;
    max-width: none;
    z-index: var(--layer-modal);
    padding: 10px;
}

.fieldset-timelines-loopdays-row {
    display: flex;
    gap: 6px;
    margin-bottom: 10px;
}

/* Seven Sun–Sat letter boxes, one-for-one with the calendar columns. */
.fieldset-timelines-loopdays-day {
    flex: 1;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

.fieldset-timelines-loopdays-letter {
    font-size: 13px;
    font-weight: 600;
    line-height: 1.2;
}

/* Cancel + Next side by side (operator 2026-08-26); Next greys until a
   weekday is chosen. */
.fieldset-timelines-loopdays-buttons {
    display: flex;
    gap: 8px;
}

.fieldset-timelines-loopdays-cancel,
.fieldset-timelines-loopdays-done {
    flex: 1;
    height: 36px;
}

/* Disabled Next reads properly dead in BOTH themes (operator 2026-08-26):
   the button stays but fades hard and ignores the pointer. */
.fieldset-timelines-loopdays-done:disabled {
    opacity: 0.35;
    pointer-events: none;
}

/* (The loop veil of 2026-08-26, off since 2026-08-27, is gone — the blurred
   calendar behind the weekday popup is the loop's veil since 2026-09-22.) */

/* ── Dual time picker (operator 2026-08-25): start + end wheel pairs side by
   side, one shared apply-to row. Same wheel internals/classes as the single
   (.fieldset-sessions-timepickermodal-*) — only the shell widens. */
.fieldset-timelines-timepickermodal--dual {
    width: 100%;
    max-width: 420px;
}

/* Single-wheel twin of the dual popup — the date span rows' start / end time
   picker. Half the dual's width: one pair. */
.fieldset-timelines-timepickermodal--single {
    width: 100%;
    max-width: 240px;
}

.fieldset-timelines-timepickermodal-dualrow {
    display: flex;
    gap: 10px;
}

.fieldset-timelines-timepickermodal-dualpair {
    flex: 1;
    min-width: 0;
}

.fieldset-timelines-timepickermodal-dualpair .fieldset-sublabel {
    text-align: center;
    padding: 10px 10px 0;
}

.fieldset-timelines-timepickermodal-dualpair .fieldset-sessions-timepickermodal-wheelrow {
    padding: 0;
}

/* Open-row rhythm (operator 2026-08-26): header, 10px, the wheels couple,
   10px, then the next accordion — the 4px bottom pairs with the row's own
   6px gap to make the second 10. */
.fieldset-timelines-daytimerange-expand {
    padding: 10px 0 4px;
}

/* ── Timeline tools container (operator 2026-08-25): an in-flow block under
   the undo/redo controls row — visible while the calendar has focus, pushing
   everything beneath it down; hidden when focus leaves the calendar/controls.
   Holds the tools row, the instruction row, and the loop container. */
.fieldset-timelines-tools-container {
    /* 10px, not the 12px container rhythm (operator 2026-09-19): this block's
       bottom margin collapses with the instruction line's own, so 12 here is
       what you see under the instruction. */
    margin-bottom: 10px;
}

/* The timelines pickers share the anchor: overlay stops centering (JS sets
   the modal's margin-top from the calendar's position) and the modal takes
   the full pane width. */
.fieldset-timelines-timepickermodal-overlay {
    align-items: flex-start;
}

.fieldset-timelines-timepickermodal-overlay .fieldset-sessions-timepickermodal {
    width: 100%;
    max-width: none;
}

.fieldset-timelines-tools-container > * {
    margin-bottom: 10px;
}



/* Main-form summary: one button per timeline (ticket-group summary pattern),
   grouped under group-name dividers. Name left, date range right.
   10-12-6 (operator 2026-08-24): 6px between sibling timeline buttons; 10px
   from a group's last button up to the NEXT group's divider (margin-top on
   dividers after the first — the one sanctioned above-margin, mirroring the
   label rule's 6px below the divider itself). */
.fieldset-timelines-summary-rows > * {
    /* Ungrouped / single-group list: obeys the tp legend's 8px row rhythm
       (operator 2026-08-24 — "10 too big, 6 too small"). */
    margin-bottom: 8px;
}
.fieldset-timelines-summary-rows > *:last-child {
    margin-bottom: 0;
}

.fieldset-timelines-summary-row {
    justify-content: space-between;
}

/* Empty-state prompt row: one icon + one text span — left-aligned like the
   sessions summary, never space-between. */
.fieldset-timelines-summary-row--prompt {
    justify-content: flex-start;
}

.fieldset-timelines-summary-name {
    flex: 1 1 auto;
    min-width: 0;
    /* Titles truncate; the date range on the right stays solid (operator
       2026-08-24). Base class already carries nowrap/ellipsis — restated
       here so the guarantee survives base-class changes. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.fieldset-timelines-summary-range {
    flex: 0 0 auto;
    font-size: 13px;
    color: rgba(255, 255, 255, 0.6);
    white-space: nowrap;
}

/* ── Timelines accordion header furniture (operator 2026-09-19) ─────────────
   From the right: X, drag handle, arrow. The arrow and its rotation are the
   Form Builder category accordion's own (formbuilder.css ~103/~129) and the
   drag slot copies its handle (~133). Both sit in fixed 36px slots so the
   row never jolts when the X hides itself on a single group. */
.fieldset-timelines-timeline-arrow {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.fieldset-timelines-timeline-arrow::before {
    content: '';
    display: block;
    width: 14px;
    height: 14px;
    background-color: currentColor;
    -webkit-mask-image: var(--ui-icon-arrow-down);
    mask-image: var(--ui-icon-arrow-down);
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    transition: transform 0.2s;
    transform-origin: center;
}

.fieldset-timelines-timeline-arrow--open::before {
    transform: rotate(180deg);
}

/* The bar's completeness dot sits INSIDE the header text and keeps the one
   dot rule's size and colour (completeness.css). The 3px lift is PLACEMENT
   only: the ● glyph inks 2px above its baseline while the words' own visual
   centre is 5px above it, so on a plain baseline the dot reads low against
   the name (measured on staging, operator 2026-09-19). */
.fieldset-timelines-timeline-header-dot {
    position: relative;
    top: -3px;
}

/* "Timeline N" never shrinks — the date range is the part that gives way. */
.fieldset-timelines-timeline-header-text {
    flex: 0 0 auto;
}

/* DATE RANGE (operator 2026-09-19): right-aligned against the controls in the
   summary row's own size and colour (.fieldset-timelines-summary-range).
   The bar is a BLUE BAND IN BOTH THEMES (accordion-class-3: blue-950 dark,
   blue-600 light, white text), so the range is a white tone in both — never
   a theme-flipping token, which went dark grey on the light band (caught
   2026-09-20). Light twin in themes.css, beside the header dot's. Too narrow: the
   weekdays drop first (sooner on a bar showing all three controls), then the
   ellipsis is the final backstop. Widths are the fixed parts plus the longest
   range, "Sat 19 Sep, 2027 – Sun 20 Sep, 2028" at 13px. */
.fieldset-timelines-timeline-header-range {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 13px;
    color: rgba(255, 255, 255, 0.6);
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

@container (max-width: 410px) {
    .fieldset-timelines-timeline-header-range-weekday {
        display: none;
    }
}

@container (max-width: 490px) {
    .fieldset-timelines-timeline-header--several .fieldset-timelines-timeline-header-range-weekday {
        display: none;
    }
}

/* The X wears its own 4px left margin for the Ticket Pricing rows, where
   there is no container gap. Here the header controls already space their
   children 4px apart, so that margin doubled the gap between the drag handle
   and the X while the arrow kept 4px (operator 2026-09-19). */
.fieldset-timelines-timeline-header .fieldset-timelines-timeline-remove.clear-button {
    margin-left: 0;
}

/* THE EDITOR AREA (operator 2026-09-19): the open timeline mounts the real
   editor here; the others stand a box of the same height in its place, so
   moving between timelines never yanks the page. Height = the calendar's own
   visibleRows 5 plus its weekday row, 36px each. */
.fieldset-timelines-editor-mount {
    margin-bottom: 10px;
}

.fieldset-timelines-timeline-drag {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
}

/* Open header squares off its bottom corners so it reads as the top of the
   expanded group — the Form Builder's own open rule (formbuilder.css ~58). */
.fieldset-timelines-timeline-header.accordion-header.fieldset-timelines-timeline-header--open {
    border-radius: 8px 8px 0 0;
}





/* Range and Loop wear green when chosen; Erase wears red through the danger
   modifier (operator 2026-09-19). Hover on a chosen tool keeps its colour,
   the same way base.css keeps a selected class-2 blue under the pointer. */
.fieldset-timelines-tool--green[aria-selected="true"],
.fieldset-timelines-tool--green[aria-selected="true"]:hover {
    background: var(--green-600);
    border-color: transparent;
    color: var(--website-white);
}


