/* =============================================================================
   settings.css - Settings screen (language, theme, account, save, distributions).

   Reference: `.docs/steps/6.md` point 3. Colors come exclusively from
   `css/themes.css`; the buttons, the panels and the pickers reuse the shared
   classes of `css/base.css` (`.btn`, `.panel`) and `css/views/onboarding.css`
   (`.lang-switch`).
   ============================================================================= */

.settings {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.settings__panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Sub-screens embedded in the settings page (promo codes, gift history). They follow the panels
   with a separator so the screen keeps its "stack of blocks" reading order. */
.settings__subview {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.settings__title {
  font-size: var(--font-size-md);
  font-weight: 700;
}

.settings__help {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* The pickers reuse `.lang-switch`; they may wrap on a narrow screen. A pill radius is meant for
   ONE line: as soon as the fifth theme drops to a second row, the huge arcs of the outer pill cut
   inside the box while the buttons keep their full width, so the row ends look like they escape
   the border. The container therefore takes a small, rectangular radius, and its options follow so
   the active background never pokes out of the corner. */
.settings__choices {
  flex-wrap: wrap;
  align-self: flex-start;
  border-radius: var(--radius-md);
}

.settings__choices .lang-switch__option {
  border-radius: var(--radius-sm);
}

.settings__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.settings__actions .btn {
  flex: 1 1 auto;
}

/* --- Sound switch --------------------------------------------------------- */

/* The switch itself is a shared control, declared in `css/base.css` (`.switch`) since the detail of
   a card uses it too. Only its alignment belongs here: a settings panel is a flex COLUMN, where the
   default `stretch` would give the button the whole width of the panel. */
.settings__panel .switch {
  align-self: flex-start;
}

/* --- Notification kinds --------------------------------------------------- */

/* One labelled switch per kind. The label is a text node the view never rewrites, so the caption
   of the switch itself can stay the short "Activé"/"Désactivé" the other switches use. */
.settings__toggles {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.settings__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}

.settings__toggle:last-child {
  border-bottom: none;
}

.settings__toggle-label {
  font-size: var(--font-size-sm);
  color: var(--color-text);
}

/* The panel is a flex column: a row must keep its switch on the right, not stretch it. */
.settings__toggle .switch {
  align-self: center;
}

/* --- Animation modes ------------------------------------------------------ */

/* Badge carried by the parodic option of the picker ("EXPLOSIF BLAGUE"): the joke needs no long
   explanation, the badge says it on the button itself. */
.anim-option__badge {
  margin-left: var(--space-2);
  padding: 1px var(--space-2);
  border-radius: var(--radius-pill);
  background-color: var(--color-warning);
  color: var(--color-accent-contrast);
  font-size: var(--font-size-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.lang-switch__option.is-parodic {
  border-style: dashed;
  border-color: var(--color-warning);
}

/* --- Animation demo ------------------------------------------------------- */

/* A miniature of an opening: one card that flips and the five summary thumbnails. It reuses the
   REAL classes of the game (`.card-reveal__card`, `.card-reveal__summary-item`) so what the player
   sees here is exactly what the opening does, in the mode selected. */
.anim-demo {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface-alt);
  /* The parodic shake and the comic drop are contained: the panel never widens. */
  overflow: hidden;
}

.anim-demo__label {
  font-size: var(--font-size-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.anim-demo__stage {
  display: grid;
  place-items: center;
  min-height: 6.5rem;
  /* Required by the flip of the card (same value as `.opening__stage`). */
  perspective: 1200px;
}

.anim-demo__card {
  display: block;
  width: 4.25rem;
  pointer-events: none;
  transform-style: preserve-3d;
}

/* The demo cards are built as `<span>`s (a settings panel must not contain a button inside a
   button): they have to be blockified explicitly, otherwise the inline box ignores
   `aspect-ratio` and the card collapses to zero height. */
.anim-demo__tile {
  display: block;
}

/* The doubled class beats `.card-reveal--summary` of `css/components/card-reveal.css`, which is
   loaded AFTER this file: the demo always shows its five thumbnails on one row, whatever the
   screen. */
.anim-demo .anim-demo__tiles {
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-2);
  margin-top: 0;
  perspective: none;
}

/* The demo cards carry no illustration: a dashed border makes it obvious they are placeholders. */
.anim-demo__stage .card-reveal__face,
.anim-demo__tile .card-reveal__face {
  border-style: dashed;
  box-shadow: none;
}

.anim-demo__tile .card-reveal__card {
  display: block;
  width: 100%;
  pointer-events: none;
  box-shadow: none;
}

.anim-demo__play {
  align-self: flex-start;
}

/* --- Foil intensity ------------------------------------------------------- */

/* The slider drives the custom property `--foil-intensity` of `css/components/card-shine.css` (see
   `js/utils/FoilManager.js`). It sits right under the animation demo on purpose: the demo card is a
   mythic, so dragging the thumb shows the strength being chosen instead of describing it. The track
   and the thumb are left to the browser, colored with `accent-color` - a themed variable, so all
   three palettes stay in charge, and nothing has to be re-styled per vendor. */
.foil-slider {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

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

.foil-slider__label {
  font-size: var(--font-size-sm);
  color: var(--color-text);
}

/* Tabular figures: the value must not shift left and right while the thumb moves. */
.foil-slider__value {
  font-variant-numeric: tabular-nums;
  font-size: var(--font-size-sm);
  font-weight: 700;
  color: var(--color-accent);
}

.foil-slider__input {
  width: 100%;
  accent-color: var(--color-accent);
  cursor: pointer;
}

.foil-slider__input:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* --- UTC clock ------------------------------------------------------------ */

/* Same pill as the header clock (`css/base.css`), so the time reads identically wherever it is
   displayed. The header one is hidden on a phone: this panel is then the only place to see it. */
.settings__clock {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  align-self: flex-start;
  padding: var(--space-2) var(--space-3);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-pill);
  background-color: var(--color-surface-alt);
  font-variant-numeric: tabular-nums;
}

.settings__clock-value {
  font-size: var(--font-size-lg);
  font-weight: 700;
  color: var(--color-text);
}

.settings__clock-day {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}

/* An untrusted time (no provider answered) is flagged like the header clock. */
body[data-connection="offline"] .settings__clock {
  border-style: solid;
  border-color: var(--color-warning);
}

body[data-connection="offline"] .settings__clock-value {
  color: var(--color-warning);
}

/* --- Account UUID --------------------------------------------------------- */

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

.settings__uuid-value {
  flex: 1 1 14rem;
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-alt);
  color: var(--color-text);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: var(--font-size-xs);
  overflow-wrap: anywhere;
  user-select: all;
}

/* --- Sound families ------------------------------------------------------- */

/* One row per family: its switch on the right, its volume slider underneath. The global switch is
   the gate: when it is off the whole block is hidden by `syncSoundCategories()`. */
.settings__sound {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

.settings__sound-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-alt);
}

.settings__sound-row[data-enabled="false"] {
  opacity: 0.65;
}

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

.settings__sound-slider[aria-disabled="true"],
.settings__sound-row .foil-slider__input:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

@media (min-width: 768px) {
  .settings {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }

  .settings__actions .btn {
    flex: 0 1 auto;
  }
}

/* --- Release notes (`settings/changelog.json`) ---------------------------- */

/* The panel takes the whole width of the grid: a note is a sentence, and half a screen would break
   it in three. Below 768px the grid is a single column anyway. */
.settings__panel--wide {
  grid-column: 1 / -1;
}

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

.changelog__notice {
  margin: 0;
}

/* One version: the browser's own `<details>` marker already says the line opens, so the block only
   adds a frame. The newest version is unfolded by the view. */
.changelog__version {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-alt);
}

.changelog__summary {
  padding: var(--space-2) var(--space-3);
  font-weight: 700;
  cursor: pointer;
}

.changelog__notes {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding: 0 var(--space-3) var(--space-3);
  list-style: none;
}

/* One note: its kind on the left, its sentence on the right. The transparent border is the room
   the important ones paint over, so nothing shifts when a note is flagged. */
.changelog__note {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  padding-left: var(--space-2);
  border-left: 2px solid transparent;
}

.changelog__badge {
  flex: 0 0 auto;
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  background-color: var(--color-surface);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* A kind the game knows gets a colour; any other keeps the muted pill and the word of the file. */
.changelog__note[data-type="feature"] .changelog__badge {
  color: var(--color-success);
}

.changelog__note[data-type="fix"] .changelog__badge {
  color: var(--color-accent);
}

.changelog__note.is-important {
  border-left-color: var(--color-warning);
}

.changelog__star {
  margin-left: var(--space-1);
  color: var(--color-warning);
}

.changelog__text {
  flex: 1 1 12rem;
  margin: 0;
  font-size: var(--font-size-sm);
}

/* --- Sections (tabs) ------------------------------------------------------ */

/* The page grew into a long stack of panels: four sections show one group at a time, which is what
   keeps it readable on a phone. The strip scrolls sideways rather than wrapping, so it never takes
   two rows; the active button takes the accent of the palette, like `.lang-switch__option.is-active`
   does for the pickers. */
.settings__tabs {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-2);
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-alt);
  scrollbar-width: thin;
}

.settings__tab {
  flex: 0 0 auto;
  padding: var(--space-2) var(--space-3);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--color-text-muted);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
}

.settings__tab:hover {
  color: var(--color-text);
}

.settings__tab.is-active {
  border-color: var(--color-accent);
  background-color: var(--color-accent);
  color: var(--color-accent-contrast);
}

.settings__tab:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* A panel keeps the rhythm of the page it replaced. `hidden` needs its own rule: a class selector
   would otherwise beat the `display: none` the attribute carries in the user agent stylesheet. */
.settings__tabpanel {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.settings__tabpanel[hidden] {
  display: none;
}

/* --- Premium offer (`SettingsView`, "Premium" section) ------------------- */

/* The offer reads as a single object: its price, what it grants, then the button that opens its
   dialog. A dashed frame says it is a separate thing from the preferences above - it is the only
   panel of this page that talks about money. */
.premium {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  margin-top: var(--space-3);
  padding: var(--space-4);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-alt);
}

.premium__price {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin: 0;
}

.premium__amount {
  font-size: var(--font-size-xl);
  font-weight: 700;
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
}

.premium__period {
  color: var(--color-text-muted);
}

.premium__perks {
  margin: 0;
  padding-left: 1.1rem;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.premium__perks li + li {
  margin-top: var(--space-1);
}

/* --- Error report (`SettingsView`, "Rapport d'erreurs" section) ---------- */

/* One row per recorded incident: the left edge carries the severity, the badge says it in words,
   and the code stays selectable so a player can quote it. A minor incident is not a broken screen
   (the game continued), which is exactly why it is listed here instead of in a popup. */
.error-log {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.error-log__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-warning);
  border-radius: var(--radius-sm);
  background-color: var(--color-surface-alt);
}

.error-log__item[data-severity='blocking'] {
  border-left-color: var(--color-accent);
}

.error-log__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
}

.error-log__badge {
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  background-color: var(--color-warning);
  color: var(--color-accent-contrast);
  font-size: var(--font-size-sm);
  font-weight: 700;
}

.error-log__item[data-severity='blocking'] .error-log__badge {
  background-color: var(--color-accent);
}

.error-log__code {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  user-select: all;
}

.error-log__message {
  margin: 0;
  overflow-wrap: anywhere;
}

.error-log__meta {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.error-log__release:empty {
  display: none;
}

/* --- Wide screens --------------------------------------------------------- */

/* From the tablet up the page lays its panels out two by two, but the strip of sections always stays
   ABOVE them, on a full-width row of its own. A strip on the left and its panel on the right reads
   as two unrelated columns, and the section that was picked became hard to find back. The panels
   carry the two columns instead, so every section keeps the layout of a phone, doubled. */
@media (min-width: 768px) {
  .settings__tabs,
  .settings__tabpanel,
  .settings__subview {
    grid-column: 1 / -1;
  }

  .settings__tabpanel {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }
}
