/* css/components.css — the 9-slice panel materials, buttons and shared widgets
   (WP-070/073, 12 § Materials, § Components).

   Three rules run through everything here and each is 12's, not a preference:

   1. `border-image: url(…) 16 fill round` at NATIVE scale. The sheets are 48×48 with 16 px slices,
      so corners are never stretched and edges tile with `round` rather than `stretch` — a stretched
      pixel corner is the single clearest way to make pixel art look like a mistake.
   2. **No `border-radius` anywhere.** The pixel edges of the 9-slice ARE the corner treatment.
      Rounding them would blur exactly the thing the art draws sharply.
   3. `image-rendering: pixelated` on every element carrying a border-image, or the browser
      smooths the slices at any dpr above 1 and the whole material turns to mush. */

.panel-parchment,
.panel-wood,
.panel-iron {
    border-style: solid;
    border-width: 16px;
    image-rendering: pixelated;
    border-radius: 0; /* stated, not omitted: 12 forbids it and a UA sheet may not */
}

/* 12 § Materials: content surfaces — dialogue, tooltips, map, cards. */
.panel-parchment {
    border-image: url('../assets/ui/panel_pergament.png') 16 fill round;
}

/* Frames and menus — pause menu, settings, inventory frame. */
.panel-wood {
    border-image: url('../assets/ui/panel_holz.png') 16 fill round;
}

/* Destructive/combat accents only — delete confirm, death border. Iron is a WARNING material:
   using it for ordinary chrome would spend the one visual signal the UI has for "this is final". */
.panel-iron {
    border-image: url('../assets/ui/panel_eisen.png') 16 fill round;
}

/* ── Form controls ─────────────────────────────────────────────────────────────────────── */

/* The UA paints range thumbs and checkboxes in the browser's own accent — a purple, inside a
   wood-and-parchment UI. `accent-color` retints them in one line while leaving the native controls
   intact: they already handle keyboard, drag, touch and RTL correctly, and a hand-built slider
   would have to re-earn all of that to look the same. */
input[type='range'],
input[type='checkbox'] {
    accent-color: var(--ui-gold);
}

/* ── Buttons ───────────────────────────────────────────────────────────────────────────── */

.button-wood {
    border-style: solid;
    border-width: 16px;
    border-image: url('../assets/ui/panel_holz.png') 16 fill round;
    border-radius: 0;
    image-rendering: pixelated;
    padding: 0 var(--space-3);
    /* 16 px slices top and bottom, so a 48 px button leaves 16 px of tiling middle — the edge slices
       end up nearly touching and the material reads as two corners rather than a plank. 56 gives the
       middle band room to actually repeat, and keeps the row a comfortable click target. */
    min-height: 56px;
    background: transparent;
    color: var(--ui-parchment);
    font: inherit;
    cursor: pointer;
    /* The label must stay crisp even though the frame is pixelated: `image-rendering` inherits to
       the background, not to text, so this only affects the border-image. */
}

.button-wood:hover:not(:disabled),
.button-wood:focus-visible {
    filter: brightness(1.15);
}

.button-wood:active:not(:disabled) {
    filter: brightness(0.9);
}

.button-wood:disabled {
    filter: grayscale(0.7) brightness(0.6);
    cursor: not-allowed;
}

/* A visible focus ring is not decoration — it is the only way a keyboard player knows where they
   are. `:focus-visible` keeps it off mouse clicks, where it would read as noise. */
.button-wood:focus-visible {
    outline: 2px solid var(--ui-gold);
    outline-offset: 2px;
}

/* ── Toasts (12 § Notifications) ────────────────────────────────────────────────────────── */

/* 12: bottom-center queue, max 3 visible, newest at bottom. The column is NOT reversed — newest is
   simply appended, so DOM order and reading order agree and a screen reader hears them in the order
   they happened. */
#notification-root {
    position: absolute;
    /* `top: auto; right: auto` are load-bearing, not tidiness. main.css stretches every UI root with
       `#ui-root > * { inset: 0 }`, which has the SAME specificity as this rule — so setting only
       `bottom`/`left` leaves that rule's `top: 0` and `right: 0` in force, the root stays a
       full-height box, and a column that packs from flex-start puts every toast at the TOP of the
       screen. Measured: the toast landed at y=0. Releasing both is what makes `bottom` mean bottom.
       (Same species as `.screen-title`'s `position: relative` quietly outranking `.screen`.) */
    top: auto;
    right: auto;
    bottom: var(--space-4);
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    align-items: center;
    pointer-events: none; /* the queue must never swallow a click meant for the world beneath it */
}

.toast {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    max-width: 32rem;
    color: var(--ui-ink); /* parchment panel: ink is the contrast pair the floor is measured on */
    pointer-events: auto; /* ...but the toast's own guide button must be clickable */
    opacity: 1;
    transition: opacity 300ms ease-out; /* = TOAST_FADE_MS; the JS removes the node after it */
}

.toast.is-leaving {
    opacity: 0;
}

/* Same sheet and the same reasoning as the gate seals: addressed by cell, checked against the built
   manifest (icons_ui.png, 16 px cells — toast_hinweis row 0 col 6, toast_wache row 0 col 7,
   toast_fest row 1 col 0), never guessed from 13's prose alone. */
.toast-icon {
    flex: none;
    width: 16px;
    height: 16px;
    background-image: url('../assets/ui/icons_ui.png');
    image-rendering: pixelated;
}

.toast-icon[data-icon='toast_hinweis'] { background-position: -96px 0; }
.toast-icon[data-icon='toast_wache']   { background-position: -112px 0; }
.toast-icon[data-icon='toast_fest']    { background-position: 0 -16px; }

.toast-text {
    flex: 1;
}

.toast-guide {
    flex: none;
    border: 0;
    background: var(--ui-wood);
    color: var(--ui-parchment);
    font: inherit;
    font-size: 0.875rem;
    padding: var(--space-1) var(--space-2);
    cursor: pointer;
}

.toast-guide:focus-visible {
    outline: 2px solid var(--ui-gold);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .toast { transition: none; }
}

/* ── Confirm dialog (12 § Notifications — same module, same scope) ──────────────────────── */

.dialog-backdrop {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Darkened, not opaque: the player must still see WHICH screen they are being asked about. */
    background: rgb(0 0 0 / 0.6);
}

.dialog-panel {
    width: 100%;
    max-width: 28rem;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    color: var(--ui-parchment);
}

.dialog-title {
    margin: 0;
    font-size: 1.25rem;
}

/* On the wood/iron dialog panel — brightened with the rest (owner decision, see screens.css). */
.dialog-body {
    margin: 0;
    color: var(--ui-parchment);
}

.dialog-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
}

/* The destructive button is gold-ringed on the iron panel: findable, but never the default — the
   safe button holds focus (see showConfirmDialog). */
.panel-iron .dialog-confirm {
    outline: 2px solid var(--ui-gold);
    outline-offset: -4px;
}
