/* MODULE: css/settings.css — the slide-over settings panel (CONTRACT §12).
   Owned by the settings agent, consumed only by src/settings.js.
   Depends on css/tokens.css for every colour, radius, duration and step, and
   on the .btn / .field / .field-group / .u-* primitives in css/base.css.
   Loads nothing: no @import, no fonts, no network.

   The panel is a fixed overlay, never a route. It slides in from the inline
   end on --ease-spring. Because that curve overshoots, the panel briefly
   travels PAST its resting position — ::after paints a strip of the same
   surface beyond its trailing edge so no gap can ever flash there. */

/* ============================================================== *
 * 1. OVERLAY ROOT
 * ============================================================== */

.settings {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  overflow: hidden; /* clips the overshoot strip and the panel shadow */
  /* Without this, a touch-drag on the scrim — the whole left half of a phone
     screen — finds a non-scrollable fixed overflow container and CHAINS to the
     document, so the app rubber-bands and scrolls underneath the open panel. */
  overscroll-behavior: none;

  /* pointer-events is inherited: none here means the closing animation never
     eats a click on the app underneath, and `auto` on .is-open hands it back
     to the scrim and panel together. */
  pointer-events: none;

  /* A scrim is a cast shadow, so it must darken in BOTH themes. --ramp-900 is
     dark on ceramic; on graphite the same role is played by --ramp-300. The
     two theme selectors below mirror the cascade in tokens.css exactly. */
  --set-scrim: color-mix(in oklab, var(--ramp-900) 46%, transparent);
  --set-panel-w: min(27rem, calc(100% - var(--space-5)));
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="ceramic"]):not([data-theme="graphite"]) .settings {
    --set-scrim: color-mix(in oklab, var(--ramp-300) 82%, transparent);
  }
}

[data-theme="graphite"] .settings {
  --set-scrim: color-mix(in oklab, var(--ramp-300) 82%, transparent);
}

.settings.is-open {
  pointer-events: auto;
}

.settings__scrim {
  position: absolute;
  inset: 0;
  background-color: var(--set-scrim);
  opacity: 0;
  transition: opacity var(--dur-med) var(--ease-out);
}

.settings.is-open .settings__scrim {
  opacity: 1;
}

/* ============================================================== *
 * 2. THE PANEL
 * ============================================================== */

.settings__panel {
  position: absolute;
  inset-block: 0;
  inset-inline-end: 0;
  inline-size: var(--set-panel-w);

  display: flex;
  flex-direction: column;

  background-color: var(--surface);
  color: var(--ink);
  border-inline-start: var(--hairline-w) solid var(--hairline);
  box-shadow: var(--shadow-panel);

  transform: translateX(100%);
  transition: transform var(--dur-med) var(--ease-spring);
}

[dir="rtl"] .settings__panel {
  transform: translateX(-100%);
}

.settings.is-open .settings__panel {
  transform: translateX(0);
}

/* The overshoot backstop described in the file header. */
.settings__panel::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 100%;
  inline-size: var(--space-7);
  background-color: var(--surface);
  pointer-events: none;
}

.settings__panel:focus {
  outline: none; /* the panel takes focus on open; the ring belongs on controls */
}

.settings__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);

  padding-block: var(--space-3);
  padding-block-start: calc(var(--space-3) + var(--safe-top));
  padding-inline-start: var(--space-5);
  padding-inline-end: max(var(--space-3), var(--safe-right));

  background-color: var(--surface);
  border-block-end: var(--hairline-w) solid var(--hairline);
}

.settings__title {
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: var(--track-tight);
}

.settings__body {
  flex: 1 1 auto;
  overflow-y: auto;
  /* A scroll gesture inside the panel must never chain to the page behind it. */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;

  padding-inline-start: var(--space-5);
  padding-inline-end: max(var(--space-5), var(--safe-right));
  padding-block-end: max(var(--space-6), calc(var(--safe-bottom) + var(--space-5)));
}

/* ============================================================== *
 * 3. SECTIONS
 * ============================================================== */

.set-section {
  padding-block: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.set-section + .set-section {
  border-block-start: var(--hairline-w) solid var(--hairline);
}

/* The slot src/settings.js reserves in Appearance for src/wear.js's Patina rows
   (PHASE3 §4). It must not become a box: that file's rows are built to sit
   directly in this flex column and lean on its `gap` — its figure line carries a
   -8px top margin to close up under the toggle — so a wrapper with no gap of its
   own makes the figure overlap the hint above it by exactly that 8px. Measured,
   not guessed. `display: contents` hands the rows straight to the column.
   Its own wrapper, .tt-wear-set, is display:contents for the same reason. */
.set-wear {
  display: contents;
}

.set-section__title {
  font-size: var(--step--1);
  font-weight: 600;
  line-height: 1;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

.set-section__note {
  font-size: var(--step--1);
  line-height: var(--lh-snug);
  color: var(--ink-3);
  margin-block-start: calc(var(--space-2) * -1);
}

/* ============================================================== *
 * 4. ROWS
 * ============================================================== */

.set-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-block-size: var(--tap);
}

.set-row--stack {
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-1);
}

.set-row__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-inline-size: 0;
}

.set-row__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}

.set-row__title {
  font-size: var(--step-0);
  font-weight: 500;
  line-height: var(--lh-snug);
  color: var(--ink);
  cursor: pointer;
}

.set-row__hint {
  font-size: var(--step--1);
  line-height: var(--lh-snug);
  color: var(--ink-3);
}

/* ============================================================== *
 * 5. THE SWITCH
 *    A checkbox input, invisible but full-size, laid over a track and a
 *    thumb. On press the thumb squashes wider and its shadow moves inside,
 *    so the control answers under the finger before the state changes.
 * ============================================================== */

.switch {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 56px;
  block-size: var(--tap); /* the whole 44px band is the target */
}

.switch__input {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.switch__track {
  position: relative;
  inline-size: 52px;
  block-size: 30px;
  border-radius: var(--radius-pill);
  background-color: var(--bg-sunk);
  box-shadow: var(--shadow-field);
  pointer-events: none;
  transition:
    background-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

.switch__thumb {
  position: absolute;
  inset-block-start: 3px;
  inset-inline-start: 3px;
  inline-size: 24px;
  block-size: 24px;
  border-radius: var(--radius-pill);
  background-color: var(--bg-raised);
  box-shadow: var(--shadow-raise);
  transition:
    transform var(--dur-med) var(--ease-spring),
    inline-size var(--dur-press) var(--ease-out),
    box-shadow var(--dur-press) var(--ease-out);
}

.switch__input:checked ~ .switch__track {
  background-color: var(--signal);
  box-shadow:
    inset 0 1px 2px rgba(0, 0, 0, 0.28),
    inset 0 -1px 0 color-mix(in oklab, var(--on-signal) 22%, transparent);
}

.switch__input:checked ~ .switch__track .switch__thumb {
  transform: translateX(22px);
}

[dir="rtl"] .switch__input:checked ~ .switch__track .switch__thumb {
  transform: translateX(-22px);
}

/* THE PRESS. The thumb stretches 4px and sinks. When it is already thrown,
   the travel drops to 18px so the wider thumb still lands inside the track. */
.switch__input:active ~ .switch__track .switch__thumb {
  inline-size: 28px;
  box-shadow: var(--shadow-press);
}

.switch__input:checked:active ~ .switch__track .switch__thumb {
  transform: translateX(18px);
}

[dir="rtl"] .switch__input:checked:active ~ .switch__track .switch__thumb {
  transform: translateX(-18px);
}

.switch__input:focus-visible ~ .switch__track {
  outline: var(--ring-w) solid var(--signal);
  outline-offset: var(--ring-offset);
}

@media (hover: hover) {
  .switch__input:hover:not(:checked) ~ .switch__track .switch__thumb {
    background-color: color-mix(in oklab, var(--bg-raised) 94%, var(--ink));
  }
}

/* ============================================================== *
 * 6. SEGMENTED RADIO GROUP
 *    A recessed trough with one raised key latched inside it.
 * ============================================================== */

.set-seg {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.set-seg__legend {
  display: block;
  padding: 0;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

.set-seg__opts {
  display: flex;
  /* Same metrics and same depth token as .segmented in index.html — one control,
     one treatment, both derived from --space-1 rather than magic 2px/3px. */
  gap: calc(var(--space-1) / 2);
  padding: var(--space-1);
  border-radius: var(--radius-pill);
  background-color: var(--bg-sunk);
  box-shadow: var(--shadow-well-s);
}

.set-seg__opt {
  position: relative;
  flex: 1 1 0;
  display: flex;
  min-inline-size: 0;
  min-block-size: var(--tap);
}

.set-seg__opt input {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.set-seg__opt span {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);

  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;

  pointer-events: none;
  transition:
    background-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    transform var(--dur-press) var(--ease-out);
}

.set-seg__opt input:checked + span {
  background-color: var(--bg-raised);
  color: var(--ink);
  box-shadow: var(--shadow-raise);
}

.set-seg__opt input:active + span {
  transform: translateY(1px);
}

.set-seg__opt input:focus-visible + span {
  outline: var(--ring-w) solid var(--signal);
  outline-offset: var(--ring-offset);
}

@media (hover: hover) {
  .set-seg__opt input:hover:not(:checked) + span {
    color: var(--ink-2);
  }
}

.set-seg__hint {
  font-size: var(--step--1);
  line-height: var(--lh-snug);
  color: var(--ink-3);
}

/* ============================================================== *
 * 7. SUB-BLOCK (warning marks)
 * ============================================================== */

.set-sub {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border-radius: var(--radius-m);
  background-color: var(--surface-2);
}

.set-sub__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.set-sub__title {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

.set-sub__reset {
  /* Reads small, but keeps the full 44px target height. */
  padding-inline: var(--space-2);
  font-size: var(--step--1);
  margin-block: calc(var(--space-2) * -1);
}

.set-sub__hint {
  font-size: var(--step--1);
  line-height: var(--lh-snug);
  color: var(--ink-3);
}

.set-marks {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.set-mark {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--tap);
  padding-inline-start: var(--space-4);
  border-radius: var(--radius-pill);
  background-color: var(--bg-raised);
  box-shadow: var(--shadow-raise);
}

.set-mark__label {
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}

.set-mark__x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--tap);
  block-size: var(--tap);
  border-radius: var(--radius-pill);
  color: var(--ink-3);
  cursor: pointer;
  touch-action: manipulation;
  transition:
    color var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out),
    transform var(--dur-press) var(--ease-out);
}

@media (hover: hover) {
  .set-mark__x:hover {
    color: var(--signal-text);
    background-color: color-mix(in oklab, var(--signal) 12%, transparent);
  }
}

.set-mark__x:active {
  transform: translateY(1px);
  color: var(--signal-text);
}

.set-marks__empty {
  font-size: var(--step--1);
  line-height: var(--lh-snug);
  color: var(--ink-3);
}

.set-marks__add {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.set-marks__input {
  inline-size: 5rem;
  flex: none;
}

/* The engraved unit beside the field, the way a scale is marked on the case. */
.set-marks__unit {
  margin-inline-start: calc(var(--space-1) * -1);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ============================================================== *
 * 8. VOLUME
 * ============================================================== */

.set-volume__value {
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--ink-2);
}

.set-slider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.set-slider__test {
  flex: none;
  color: var(--ink-2);
}

.set-range {
  flex: 1 1 auto;
  inline-size: 100%;
  min-block-size: var(--tap);
  margin: 0;
  padding: 0;
  background-color: transparent;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
}

.set-range:focus {
  outline: none;
}

/* WebKit / Blink. Track and thumb must be declared in separate rules from the
   Gecko ones — a single unknown pseudo-element invalidates the whole list.
   --set-vol is written by src/settings.js on every input event: the track is a
   level meter, so the quantity is drawn in the signal colour like the disc. */
.set-range::-webkit-slider-runnable-track {
  block-size: 6px;
  border-radius: var(--radius-pill);
  background-color: var(--bg-sunk);
  background-image: linear-gradient(
    to right,
    var(--signal) var(--set-vol, 70%),
    transparent var(--set-vol, 70%)
  );
  box-shadow: var(--shadow-field);
}

[dir="rtl"] .set-range::-webkit-slider-runnable-track {
  background-image: linear-gradient(
    to left,
    var(--signal) var(--set-vol, 70%),
    transparent var(--set-vol, 70%)
  );
}

.set-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  inline-size: 26px;
  block-size: 26px;
  /* (track 6 − thumb 26) / 2, so the thumb straddles the track centre line. */
  margin-block-start: -10px;
  border-radius: var(--radius-pill);
  background-color: var(--bg-raised);
  box-shadow: var(--shadow-raise);
}

.set-range:active::-webkit-slider-thumb {
  box-shadow: var(--shadow-press);
}

.set-range:focus-visible::-webkit-slider-thumb {
  outline: var(--ring-w) solid var(--signal);
  outline-offset: var(--ring-offset);
}

/* Gecko */
.set-range::-moz-range-track {
  block-size: 6px;
  border-radius: var(--radius-pill);
  background-color: var(--bg-sunk);
  box-shadow: var(--shadow-field);
}

.set-range::-moz-range-progress {
  block-size: 6px;
  border-radius: var(--radius-pill);
  background-color: var(--signal);
}

.set-range::-moz-range-thumb {
  inline-size: 26px;
  block-size: 26px;
  border: 0;
  border-radius: var(--radius-pill);
  background-color: var(--bg-raised);
  box-shadow: var(--shadow-raise);
}

.set-range:active::-moz-range-thumb {
  box-shadow: var(--shadow-press);
}

.set-range:focus-visible::-moz-range-thumb {
  outline: var(--ring-w) solid var(--signal);
  outline-offset: var(--ring-offset);
}

/* ============================================================== *
 * 9. DAY WINDOW
 * ============================================================== */

.set-times {
  display: flex;
  gap: var(--space-3);
}

.set-times .field-group {
  flex: 1 1 0;
  min-inline-size: 0;
}

.set-time {
  font-family: var(--font-num);
  font-size: var(--step-1);
  text-align: center;
  appearance: none;
  -webkit-appearance: none;
}

/* ============================================================== *
 * 10. MESSAGES, NOTES, DATA ACTIONS
 * ============================================================== */

.set-msg {
  min-block-size: 1.25em;
  font-size: var(--step--1);
  line-height: var(--lh-snug);
  color: var(--ink-3);
}

.set-msg.is-error {
  color: var(--signal-text);
}

/* The calm inline note: a quiet slab with one cool rule down its leading edge.
   Used for "this iPhone cannot vibrate" and the private-browsing warning —
   information, never an alarm. */
.set-note {
  padding: var(--space-3);
  padding-inline-start: var(--space-4);
  border-radius: var(--radius-m);
  background-color: var(--surface-2);
  box-shadow: inset 2px 0 0 color-mix(in oklab, var(--accent-cool) 65%, transparent);
  font-size: var(--step--1);
  line-height: var(--lh-snug);
  color: var(--ink-2);
}

[dir="rtl"] .set-note {
  box-shadow: inset -2px 0 0 color-mix(in oklab, var(--accent-cool) 65%, transparent);
}

.set-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.set-confirm {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-m);
  background-color: var(--surface-2);
  box-shadow: inset 2px 0 0 color-mix(in oklab, var(--signal) 65%, transparent);
}

.set-confirm__text {
  font-size: var(--step--1);
  line-height: var(--lh-snug);
  color: var(--ink-2);
}

.set-danger {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-block-start: var(--space-2);
}

.set-danger__btn {
  color: var(--signal-text);
}

/* Step two of the confirm: the key itself turns into the signal. It is the only
   place in the panel where the signal colour is used as a fill. */
.set-danger__btn.is-armed {
  /* --signal-key, not --signal: this key carries a white label. */
  background-color: var(--signal-key);
  color: var(--on-signal);
  box-shadow:
    inset 0 1px 0 color-mix(in oklab, var(--on-signal) 22%, transparent),
    0 0 0 1px color-mix(in oklab, var(--signal-key) 70%, var(--ink)),
    0 1px 1px rgba(0, 0, 0, 0.14),
    0 2px 3px rgba(0, 0, 0, 0.09);
}

@media (hover: hover) {
  .set-danger__btn.is-armed:hover {
    background-color: color-mix(in oklab, var(--signal-key) 92%, var(--ink));
  }
}

/* ============================================================== *
 * 11. WIDE VIEWPORTS
 * ============================================================== */

@media (min-width: 40rem) {
  .settings__head {
    padding-inline-start: var(--space-6);
  }

  .settings__body {
    padding-inline-start: var(--space-6);
    padding-inline-end: max(var(--space-6), var(--safe-right));
  }
}

/* ============================================================== *
 * 12. PREFERENCE OVERRIDES
 *     base.css already collapses every duration under reduced motion; these
 *     rules only remove the travel so nothing appears to slide at all.
 * ============================================================== */

@media (prefers-reduced-motion: reduce) {
  .settings__panel {
    transition: none;
    transform: none;
    opacity: 0;
    visibility: hidden;
  }

  .settings.is-open .settings__panel {
    opacity: 1;
    visibility: visible;
  }

  .switch__thumb,
  .set-seg__opt span {
    transition: none;
  }
}

@media (forced-colors: active) {
  .settings__panel {
    border-inline-start: 1px solid CanvasText;
  }

  .switch__track {
    border: 1px solid ButtonBorder;
    background-color: ButtonFace;
    box-shadow: none;
    forced-color-adjust: none;
  }

  .switch__input:checked ~ .switch__track {
    background-color: Highlight;
  }

  .switch__thumb {
    background-color: ButtonText;
    box-shadow: none;
  }

  .switch__input:checked ~ .switch__track .switch__thumb {
    background-color: HighlightText;
  }

  .set-seg__opt input:checked + span {
    background-color: Highlight;
    color: HighlightText;
    box-shadow: none;
    forced-color-adjust: none;
  }

  .set-mark,
  .set-sub,
  .set-note,
  .set-confirm {
    border: 1px solid ButtonBorder;
    box-shadow: none;
  }
}
