/* The Flying Dutchman
   style.css
   Version 2.0 (October 2026): full visual redesign, accessibility and polish by Hassan Odimi.
   Version 1.0: created by 'Pirates of the Caribbean' on 09 February 2018.
*/

/*Style Sheet common to all pages*/

/* Colour tokens, named by role. Change the theme here. */
:root {
  /* sea glass: light surfaces */
  --surface: #A4B9B6;
  --surface-soft: #C0CFCC;
  --surface-faint: #D6DDDC;
  --control-strong: #567973;
  --paper: #fff;
  --paper-veil: rgba(255, 255, 255, 0.9);
  --slip-wash: rgba(255, 255, 255, 0.45);  /* lifts the stock order receipt off the ledger paper under it (F13) */

  /* kelp: dark bars */
  --bar: #254540;               /* white text 10.48:1 */
  --bar-deep: #0C2924;

  /* text */
  --ink: #000;
  --ink-on-dark: #fff;
  --ink-soft-on-dark: #96b9a5;
  --ink-muted: #4a6a65;
  --ink-deep: #15443d;
  --ink-sepia: #2a1709;         /* on the paper tabs and slips, 5.2:1 or better on their darkest pixel */
  --ink-card-soft: #43362a;     /* time on the 1850 card stock, 5.3:1 on its darkest pixel, the 0.43 floor (F11) */
  --scroll-thumb: #6e6a64;      /* docket scrollbar thumb when pointed at: a neutral grey, 3.3:1 on the lightest card-stock pixel */
  --scroll-faint: rgba(110, 106, 100, 0.35);  /* the same thumb at rest, 1.45:1 on purpose */
  --press-tint: rgba(42, 23, 9, 0.07);  /* hover tint inside the hairline buttons on the card */
  --rule-sepia: rgba(42, 23, 9, 0.35);  /* ruled lines on the phone category sheet and the order ledger */
  --paper-fold: #c9b48f;        /* the back of a folded paper corner (T8 paid slips) */
  --paper-ear: linear-gradient(45deg, var(--paper-fold) 50%, transparent 50%) top right / 26px 26px no-repeat, linear-gradient(225deg, var(--control-strong) 50%, transparent 50%) top right / 26px 26px no-repeat;
  --tab-tint: rgba(214, 140, 40, 0.3);  /* the selected phone category: a warm wash on the sheet, like the selected tab note */
  --hover-sepia: rgba(42, 23, 9, 0.08); /* hover on the sheet: sepia 4.62:1 on the darkest hovered pixel */

  /* danger */
  --danger-text: #8b0000;       /* 4.86:1 or better on every sea-glass surface */
  --danger-text-on-dark: #ffb4a8;
  --danger-fill: #AF370B;       /* white text */
  --hover-sepia: rgba(42, 23, 9, 0.12);  /* sepia ink wash behind the secondary Use buttons on the Passwords sheet (V8) */
  --hover-danger: rgba(139, 0, 0, 0.12);  /* red ink wash behind the order-row remove cross on hover and focus */
  --alert-fill: #c8102e;        /* new order, white text 5.88:1 */

  /* flags, brass */
  --flag-red: #8e1f2c;
  --stamp-red: #6a121e;         /* LOW STOCK ink: 5.0:1 on the darkest card paper under it, worn at 90 % ink and warmed by hover (flag red gave 3.8) */
  --stamp-green: #0f3d18;       /* ORDERED ink (F13): 3.11:1 or better on its worst pixel, worn at 85 % ink at the thin end (flag green gave 2.01) */
  --ink-stamp: #1c1410;        /* near-black stamp ink, OUT OF STOCK (F8) */
  --list-edge: rgba(6, 26, 22, 0.6);  /* dark kelp, the inner shadow round the drink list (F8) */
  --flag-red-light: #AD2535;
  --flag-green: #1e6b2b;
  --gold: #926e30;
  --gold-deep: #84642b;
  --brass-light: #e8c77e;       /* bevel highlight and rivet glint, never behind text; gold staff name (T6) */
  --brass-dark: #4a3412;        /* bottom of the brass plate, white text 11.9:1 */
  --iron-light: #8c9a96;        /* bevel highlight on the iron Close */
  --rust-light: #e8917e;        /* bevel highlight on the rust-red plate, never behind text */
  --rust-dark: #4a0f14;         /* bottom of the rust-red plate */

  /* 2018 originals */
  --accent-blue: #3240ff;
  --accent-lime: #2dff12;
  --bright-red: red;
  --bright-green: green;
  --bright-grey: grey;

  /* shadows */
  --shadow-lift: rgba(0, 0, 0, 0.65);
  --wood-scrim: rgba(0, 0, 0, 0.45);  /* darkens wood2 so Sail White stays 5.48:1 or better on its brightest pixel */
  --scrim: rgba(0, 0, 0, 0.6);
  --login-scrim: rgba(0, 0, 0, 0.15);  /* extra on the login box: its labels land on wood2's brightest planks */
}

/* transitions-dev motion values for the toast, the login error shake and the card hover lift */
:root {
  --toast-open: 350ms;
  --toast-close: 250ms;
  --toast-distance: 16px;
  --toast-blur: 2px;
  --toast-scale: 0.97;
  --toast-ease: cubic-bezier(0.22, 1, 0.36, 1);

  --shake-distance: 6px;
  --shake-overshoot: 4px;
  --shake-dur-a: 80ms;
  --shake-dur-b: 60ms;
  --shake-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --revert-dur: 280ms;

  --lift-distance: 2px;  /* card hover: quick in, slower out */
  --lift-in: 150ms;
  --lift-out: 250ms;
  --settle-ease: cubic-bezier(0.34, 1.36, 0.64, 1); /* things that land: 4.3 % overshoot at 64 % of the time (transitions-dev --ease-bounce) */
  --deal-dur: 400ms; /* a card dealt onto the pile (D1) */
  /* V12b ghost motion: a thing forming out of the fog shows the Dutchman's lantern green; at rest it has no tint */
  --ghost-tint: sepia(1) hue-rotate(110deg) saturate(0.5) brightness(1.5);
  --ghost-blur: 8px;
  --ghost-form: 500ms; /* a card condensing (G3) */
  --ghost-open: 900ms; /* a dialog condensing (G6) */
  --ghost-close: 400ms; /* a dialog dissolving (G6) */
  --fog-pass: 1400ms; /* a bank of mist passing (G5, G6) */
  --page-out: 700ms; /* the old page sinks into the fog (G5) */
  --page-in: 900ms; /* the new page condenses (G5) */
  --page-delay: 500ms; /* ...after waiting while the old page sinks (G5) */
  --depart-fade: 2400ms; /* the page fades while the foghorn plays (G5) */
  --depart-mist: 1000ms; /* ...and a bank of mist crosses it, ending as the fade does */
  --ghost-blow: 2700ms; /* the skull holds until here, then the fog takes it back and the card wisps appear (G3) */
  --ghost-wait: 3100ms; /* the cards condense (G3) */
  --ghost-stagger: 40ms; /* between cards (G3) */
  --bone: #b9b59c; /* the skull of smoke (G3) */
}

/* Type and spacing scale (V1): 1.25 ratio in rem, so text zooms; 4 px spacing steps */
:root {
  --text-xs: 0.8rem;       /* 12.8 px */
  --text-base: 1rem;       /* 16 px */
  --text-md: 1.25rem;      /* 20 px */
  --text-lg: 1.563rem;     /* 25 px */
  --text-xl: 1.953rem;     /* 31.25 px */
  --text-xxl: 2.5rem;      /* 40 px, the stock count on a management row (F12) */
  --text-display: clamp(1.953rem, 1.6rem + 1.2vw, 2.441rem); /* 31.25 to 39 px, the one swash greeting */

  --font-display: 'Pirata One', serif;      /* titles, greeting, names: one weight (400), no bold */
  --font-body: 'Alegreya Sans', sans-serif; /* everything else: 400, 500, 700 */

  --weight-body: 400;
  --weight-label: 500;
  --weight-heading: 700;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
}

/* Materials (V2): one scrimmed wood floor, two lifts, two corner sizes */
:root {
  --wood: linear-gradient(var(--wood-scrim), var(--wood-scrim)), url("../img/wood2.jpg");
  --shadow-raised: 0 2px 6px var(--shadow-lift), 0 10px 26px var(--shadow-lift); /* panels and tabs on the wood */
  --shadow-float: 0 2px 6px var(--shadow-lift), 0 12px 28px var(--shadow-lift);  /* buttons, menus, toasts */
  --shadow-pressed: 0 1px 2px var(--shadow-lift);                                 /* a button held down */
  --shadow-inset: inset 0 2px 4px var(--shadow-lift);                             /* a login field cut into the wood */
  --shadow-brass: inset 0 1px 0 var(--brass-light), inset 0 -2px 0 var(--shadow-lift), var(--shadow-float);
  --shadow-iron: inset 0 1px 0 var(--iron-light), inset 0 -2px 0 var(--shadow-lift), var(--shadow-float);
  --shadow-rust: inset 0 1px 0 var(--rust-light), inset 0 -2px 0 var(--shadow-lift), var(--shadow-float);
  --shadow-none: none;
  --shadow-well: inset 0 0 50px var(--list-edge), var(--shadow-raised);               /* the drink list: a dark rim inside, lifted outside */
  --felt: url("../img/textures/felt-green.webp") 0 0 / 512px;                       /* the card table baize (F11) */
  --rail: url("../img/textures/rail.webp") 0 0 / 256px;                             /* the table's rail: aged walnut, apart from the plank floor */
  --felt-vignette: rgba(0, 0, 0, 0.45);
  --shadow-contact: rgba(0, 0, 0, 0.85);                                           /* the dark patch under a torn tab */
  --shadow-felt: inset 0 0 70px var(--felt-vignette), var(--shadow-raised);        /* the table: dark rim inside, lifted outside */
  --shadow-card: 0 1px 2px var(--shadow-lift), 0 3px 8px var(--shadow-lift);       /* a playing card resting on the baize */
  --shadow-lifted: 0 3px 5px var(--shadow-lift), 0 14px 22px var(--shadow-lift); /* a card lifted by the hand */
  --shadow-coil: 0 2px 3px var(--shadow-lift);                                    /* the rope coil of a scrollbar thumb */
  --mast: #1e1d1c;  /* scrollbar track: average of mast.webp; the rope is 3.57:1 against it */
  --rope: #895e2d;  /* scrollbar thumb: average of coil.webp */
  --radius-sm: 4px;      /* buttons, inputs */
  --radius-md: 8px;      /* cards, panels, tab tops, dialogs */
  --radius-lg: 12px;     /* playing cards (F11) */
  --radius-rail: 18px;   /* the card table's wooden rail (F11) */
  --radius-round: 50%;
}

/* PAGE SHELL (F5): from 769 px wide and 600 px high the page is one screen. Rows: header, tab row, main, footer;
   only the drink list and the order list scroll. Under 600 px high (landscape phones, 200% zoom) the 2018 floats
   and normal page scrolling take over, so the list never shrinks to nothing. Phones keep their stacked layout. */
@media (min-width: 769px) and (min-height: 600px) {
    body {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto auto minmax(0, 1fr) auto;
        height: 100dvh;
        margin: 0;
    }
    body > header { grid-row: 1; }
    body > .menu { grid-row: 2; }
    body > .main_section, body > .order_list { grid-row: 3; }
    body > footer { grid-row: 4; }

    /* drink list (left) and order column (right): header, list, checkout */
    body > .main_section {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(280px, 28%);
        grid-template-rows: auto minmax(0, 1fr) auto;
        min-height: 0;
        margin: 0 2% var(--space-4); /* clear of the flag cord's nails */
    }
    .main_section > .drink_list { grid-column: 1; grid-row: 1 / 4; width: auto; height: auto; margin: 0; }
    .main_section > .selection_header { grid-column: 2; grid-row: 1; width: auto; margin: 0; }
    .main_section > .selection { grid-column: 2; grid-row: 2; width: auto; height: auto; min-height: 0; margin: 0; }
    .main_section > .checkout { grid-column: 2; grid-row: 3; width: auto; margin: 0; }
}

/* SCROLLBARS (F5): a rope coil winding up a weathered mast. Chromium and Safari draw the textures; Firefox gets plain colours.
   Chrome 121+ drops ::-webkit-scrollbar when scrollbar-color is set, so that is limited to browsers without it */
::-webkit-scrollbar { width: 16px; height: 16px; }
::-webkit-scrollbar-button { display: none; }
::-webkit-scrollbar-corner { background: var(--mast); }
::-webkit-scrollbar-track { background: url("../img/textures/mast.webp") 0 0 / 16px auto repeat-y, var(--mast); }
::-webkit-scrollbar-thumb { background: url("../img/textures/coil.webp") 0 0 / 16px auto repeat-y, var(--rope); border-radius: var(--radius-sm); box-shadow: var(--shadow-coil); }
@supports not selector(::-webkit-scrollbar) { * { scrollbar-color: var(--rope) var(--mast); } }

/* Only real weights: Alegreya Sans loads 400, 500 and 700, Pirata One only 400, so never let the browser fake bold */
body {
    font-weight: var(--weight-body);
    font-synthesis: none;
    font-variant-numeric: lining-nums tabular-nums; /* Alegreya Sans defaults to old-style figures; prices and order numbers must line up */
}

h1 { font-size: var(--text-xl); }
h2 { font-size: var(--text-lg); }
h3 { font-size: var(--text-md); }
h4 { font-size: var(--text-base); font-weight: var(--weight-label); }
h1, h2, h3, b, strong, .price { font-weight: var(--weight-heading); }
@media (min-width: 769px) { #total { font-size: var(--text-md); } } /* order total, one step under "Your Order"; the phone checkout bar keeps 16 px */

h1, h2 {
    text-align: center;
}

/*HEADER*/
header{
    overflow:hidden;
    position: relative;
}

/* Staff page titles in the customer greeting's swash (V6) */
#orders_q, #title {
    font-family: var(--font-display);
    font-weight: var(--weight-body); /* the swash has no bold */
    text-shadow: 0 1px 2px var(--ink), 0 0 8px var(--ink);
}

.title {
    /*background-color: darkgrey;*/
    float: left;
    width: 100%;
}

/* Staff label (T6): text on the wood, not a plate, so it never reads as a button. Gold role icon
   (Lucide beer / ship-wheel), white role word, gold swash name, over an edgeless dark glow.
   Gold name 6.24:1 and role 9.4:1 or better on the worst pixel */
.info {
    position: absolute;
    top: 15px;                 /* centred on the 40 px heading line at 21 px, as the credit label is on the greeting */
    right: max(0px, calc(2% - 16px)); /* ends on the panel's right edge, like .credit in customer.css; never past the screen at 769 px */
    display: grid;
    grid-template-columns: auto auto;
    column-gap: 10px;
    align-items: center;
    padding: 6px 16px;
    white-space: nowrap;
    color: var(--ink-on-dark);
    background: radial-gradient(farthest-side, var(--wood-scrim) 65%, transparent);
    text-shadow: 0 1px 2px var(--ink), 0 0 6px var(--ink);
}
.info .icon {
    grid-row: 1 / 3;
    width: 36px;
    height: 36px;
    stroke-width: 1.5;
    color: var(--brass-light);
    filter: drop-shadow(0 1px 2px var(--ink));
}
.info b {
    font-size: var(--text-xs);
    font-weight: var(--weight-label);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    line-height: 1;
}
.info span {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    line-height: 1.1;
    color: var(--brass-light);
}
@media (max-width: 1023px) {
    #orders_q, #title { padding-top: 52px; } /* the heading drops below the label (the management title reaches it at 800px) */
}
@media (max-width: 768px) {
    .info { top: 0; right: 4px; } /* as .credit on phones: the panel-edge offset would push the label off screen */
}


/* ICONS (V11): Lucide sprite img/icons.svg, drawn in the text colour */
.icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.125em;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.icon-2x { width: 2em; height: 2em; }

/* BUTTONS */

/* Native buttons replace the old clickable divs; strip browser chrome so classes keep the look */
button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    padding: 0;
    box-sizing: content-box; /* match the divs they replaced */
    cursor: pointer;
}

/* Two-tone ring: one of white or black is at least 4.58:1 on any surface */
:focus-visible {
    outline: 3px solid var(--paper);
    box-shadow: 0 0 0 6px var(--ink);
}

.h4 {
    display: block;
    font-weight: var(--weight-label);
    margin: 1.33em 0;
}
.h4.price { font-weight: var(--weight-heading); } /* drink card price */

/* The drink list on both pages: kelp-green board with random rust specks under the cards (F8); one 1024 px tile, gentex13.py */
.drink_list {
    position: relative; /* the skull and wisps of the first load (G3) sit in it */
    background: url("../img/textures/board-rust.webp") 0 0 / 1024px 1024px, var(--control-strong);
    background-blend-mode: multiply, normal;
    box-shadow: var(--shadow-well);
}

.small_button {
    margin: 0.8%;
    padding:0.8%;
    width: 15%;

    text-align: center;
    font-size: var(--text-md);

    cursor:pointer;
}

a{
    text-decoration: none;
    color: var(--ink);
    cursor:pointer;
}

a:hover {
    color: var(--ink-on-dark);
}

a:active {
    color: var(--bright-red);
}


/* LANGUAGE MENU */
.languages_menu{
    bottom: 0px;
    display: block;
    margin-left: auto;
    margin-right: auto;
    clear: both;
}

/* Flag line (V6), app footers only: worn cloth flags sewn onto a hemp cord that sags between two rusty nails.
   The cord image sags 16px; each flag sits at t = .1 .3 .5 .7 .9 along it at any width, because the first and
   last margins are set from the container width (cqw), so the drop and the angle per flag follow the cord */
@media (min-width: 769px) {
    footer {
        display: flex;
        align-items: center;
        gap: var(--space-4);
        clear: both; /* a flex footer is a new block context and would squeeze in beside the floated panels */
    }
    footer > * { float: none; }
    footer .languages_menu { flex: none; width: 464px; margin: 0 auto; } /* inline-size containment lets a flex item shrink to 0 */
    footer button { white-space: nowrap; }
    footer .undo_redo_menu { display: flex; }
}
footer .languages_menu {
    --fw: 64px;
    container-type: inline-size;
    position: relative;
    max-width: 464px;
    margin-inline: auto;
    display: flex;
    justify-content: space-between;
    height: auto;
    padding: 14px 0;
}
footer .languages_menu a {
    display: block;
    flex: none;
    margin-top: 10px; /* the flags hang clear of the cord: the top red of the Spanish flag shows */
}
footer .languages_menu a:first-child { margin-left: calc(12px + 0.1 * (100cqw - 24px) - var(--fw) / 2); }
footer .languages_menu a:last-child { margin-right: calc(12px + 0.1 * (100cqw - 24px) - var(--fw) / 2); }
footer .languages,
footer .languages_menu a:first-child .languages {
    position: relative;
    float: none;
    margin: 0;
    transform-origin: 50% 0;
}
footer .languages img {
    display: block;
    float: none;
    width: var(--fw);
    height: calc(var(--fw) * 0.625);
    margin: 0;
    border-radius: 0;
    box-shadow: var(--shadow-none);
    filter: drop-shadow(0 2px 2px var(--ink));
}
footer .languages::before { /* the sleeve's shade under the cord */
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 10px;
    background: linear-gradient(var(--wood-scrim), transparent);
    z-index: 1;
}
footer .languages_menu::before { /* the cord, ends on the nail centres */
    content: "";
    position: absolute;
    left: 12px;
    right: 12px;
    top: 2px;
    height: 40px;
    background: url("../img/textures/rope.webp") 0 0 / 100% 100%;
    filter: drop-shadow(0 2px 1px var(--ink));
    pointer-events: none;
    z-index: 2;
}
footer .languages_menu::after { /* the nails */
    content: "";
    position: absolute;
    inset: -6px 0 auto;
    height: 24px;
    background: url("../img/textures/nail.webp") left top / 24px 24px no-repeat,
                url("../img/textures/nail.webp") right top / 24px 24px no-repeat;
    pointer-events: none;
    z-index: 3;
}
footer .languages_menu a:nth-child(1) .languages { translate: 0 -4px; rotate: atan2(51.2px, 100cqw - 24px); }
footer .languages_menu a:nth-child(2) .languages { translate: 0 3.4px; rotate: atan2(25.6px, 100cqw - 24px); }
footer .languages_menu a:nth-child(3) .languages { translate: 0 6px; }
footer .languages_menu a:nth-child(4) .languages { translate: 0 3.4px; rotate: atan2(-25.6px, 100cqw - 24px); }
footer .languages_menu a:nth-child(5) .languages { translate: 0 -4px; rotate: atan2(-51.2px, 100cqw - 24px); }
@media (max-width: 768px) {
    footer .languages_menu { --fw: 56px; }
    footer .languages_menu a { min-height: 44px; } /* 56x35 flags, 44px phone target */
}
/* The Undo and Redo words show at every width, so the single footer row is tiered by width (Spanish is the widest) */
@media (min-width: 769px) and (max-width: 999px) {
    footer { gap: 6px; }
    footer .languages_menu { --fw: 36px; width: 216px; }
    footer button.small_button { padding-inline: 10px; }
    footer .undo_redo_menu button { padding: 0 8px; }
}
@media (min-width: 1000px) and (max-width: 1099px) {
    footer .languages_menu { --fw: 48px; width: 340px; }
}
@media (min-width: 1100px) and (max-width: 1249px) {
    footer .languages_menu { --fw: 56px; width: 400px; }
}
@media (max-width: 359px) {
    footer .languages_menu { --fw: 46px; }
}
/* V12: the Sound plate and its word need room on the order and stock pages (Spanish is the widest), so their flag line is smaller below 1250px */
@media (min-width: 769px) and (max-width: 1249px) {
    footer:has(#pay) button.small_button { padding-inline: 12px; }
    footer:has(#pay) .languages_menu { --fw: 34px; width: 210px; }
}
@media (min-width: 769px) and (max-width: 999px) { footer:has(#pay) .languages_menu { --fw: 30px; width: 180px; } }
@media (min-width: 769px) and (max-width: 899px) { footer:has(#pay) { flex-wrap: wrap; row-gap: 8px; } footer:has(#pay) #sound { order: 1; } } /* the plate drops to a second row when Spanish does not fit */
@media (min-width: 1250px) { footer:has(#pay) .languages_menu { --fw: 56px; width: 400px; } }

/*UNDO-REDO MENU*/

.undo_redo_menu {
/**    background-color: #a4a4a4;*/
    float: left;
    margin: 1%;
    margin-top: 1%;


}

#undo, #redo {
    float: none;
    height: 100%;
    margin-right: 8px;
    white-space: nowrap;
}
.undo_redo_menu button { min-height: 44px; padding: 0 12px; } /* a plate, not a text link; phones tighten the padding per page */
.fade {
    opacity: 0.5;
    pointer-events: none;
}


.highlight {
    background: var(--bright-grey); /*#3240ff;*/
}


/*
.undo {
    color: red;
}
.redo {
    color: green;
} */

/* TABS (V4, F7): torn sailors' notes on the wood. Idle notes are dimmed, a hovered note is clean paper,
   the selected note is warm-tinted, pulled forward and pinned with a rusty tack.
   Textures are cut from Texturelabs Paper 328, see docs/ASSETS.md. Sepia text on the idle paper: 4.67:1 on the worst pixel
   (the planned .82 gave 3.7 and .88 gave 4.09, short of 4.5) */
.menu li button {
    position: relative;
    height: 36px;
    margin-top: 4px;
    padding: 8px var(--space-3) 0;
    border: 0;
    border-radius: 0;
    color: var(--ink-sepia);
    background: url("../img/textures/tab-note1.webp") 0 0 / 100% 100% no-repeat;
    filter: brightness(.95) saturate(.7) drop-shadow(0 2px 3px var(--shadow-lift));
    transition: height var(--lift-out) var(--toast-ease), margin-top var(--lift-out) var(--toast-ease), filter var(--lift-out) var(--toast-ease);
}
.menu li:nth-child(3n+2) button { background-image: url("../img/textures/tab-note2.webp"); }
.menu li:nth-child(3n) button { background-image: url("../img/textures/tab-note3.webp"); }
.menu li:nth-child(odd) button { transform: rotate(-0.6deg); }
.menu li:nth-child(4n) button { transform: rotate(0.7deg); }

.menu li button:hover {
    height: 38px;
    margin-top: 2px;
    filter: drop-shadow(0 3px 4px var(--shadow-lift));
    transition-duration: var(--lift-in);
}

/* Selected tab: styled from aria-pressed, which the JS already sets. Keeps its own torn note; sepia 5.4:1 on the worst pixel */
.menu li button[aria-pressed="true"] {
    z-index: 2;
    height: 46px;
    margin-top: -6px;
    padding-top: 12px;
    transform: none;
    filter: saturate(2.2) sepia(.25) brightness(.96) drop-shadow(0 4px 6px var(--shadow-lift));
    color: var(--ink);
    font-size: var(--text-md);
    font-weight: var(--weight-heading);
}
.menu li button[aria-pressed="true"]::before { /* the tack: decorative */
    content: "";
    position: absolute;
    top: -3px;
    left: 50%;
    width: 18px;
    height: 18px;
    translate: -50% 0;
    border-radius: var(--radius-round);
    background: url("../img/textures/rivet.webp") center / 100% 100% no-repeat;
    filter: drop-shadow(0 1px 2px var(--shadow-lift));
}

@media (min-width: 769px) and (max-width: 1099px) {
    .menu li button { padding-inline: var(--space-2); } /* seven notes, bold when selected, stay on one row in Spanish */
}
@media (min-width: 769px) and (max-width: 849px) {
    .menu li button { padding-inline: var(--space-1); }
}

/* BUTTONS (V4): hover darkens, press sinks 1px */
.red, .blue, .light_green, .add_button .h4, .flipper, #login, #close, .close_window {
    transition: transform var(--lift-in) var(--toast-ease), filter var(--lift-in) var(--toast-ease), box-shadow var(--lift-in) var(--toast-ease);
}
.red:hover, .blue:hover, .light_green:hover, .add_button:hover .h4, .flipper:hover, #login:hover, #close:hover, .close_window:hover {
    filter: brightness(0.88);
}
.red:active, .blue:active, .light_green:active, .add_button:active .h4, .flipper:active, #login:active, #close:active, .close_window:active {
    transform: translateY(1px);
    filter: brightness(0.8);
    box-shadow: var(--shadow-pressed);
}

/* Brass plate: tarnish scan (Texturelabs Metal 132) multiplied over the gold, four rusted rivets
   (Texturelabs Details 144). Multiply only darkens, so white text is 6.97:1 or better */
.blue, #login {
    background:
        url("../img/textures/rivet.webp") left 1px top 1px / 12px 12px no-repeat,
        url("../img/textures/rivet.webp") right 1px top 1px / 12px 12px no-repeat,
        url("../img/textures/rivet.webp") left 1px bottom 1px / 12px 12px no-repeat,
        url("../img/textures/rivet.webp") right 1px bottom 1px / 12px 12px no-repeat,
        url("../img/textures/tarnish.webp") 0 0 / 400px 200px,
        linear-gradient(var(--gold) 0%, var(--gold-deep) 55%, var(--brass-dark) 100%);
    background-blend-mode: normal, normal, normal, normal, multiply, normal;
    color: var(--ink-on-dark);
    box-shadow: var(--shadow-brass);
}

/* Worn iron plates (F6): Log Out, Undo, Redo, and Update Orders on the bartender page (F7). One chipped plate texture (Texturelabs Metal 155 + 132), quieter than the brass Place Order.
   The drop shadow follows the chipped outline; box-shadow would draw a rectangle. White 4.83:1 or better on the worst pixel */
#logout, #undo, #redo, #retrieve_orders, #sound {
    background: url("../img/textures/plate-worn.webp") 0 0 / 100% 100% no-repeat;
    border: 0;
    border-radius: 0;
    box-shadow: var(--shadow-none);
    color: var(--ink-on-dark);
    text-shadow: 0 1px 1px var(--ink);
    filter: drop-shadow(0 2px 3px var(--shadow-lift));
    transition: transform var(--lift-in) var(--toast-ease), filter var(--lift-in) var(--toast-ease);
}
#logout { rotate: -0.6deg; }
#redo { rotate: 0.8deg; }
/* V12: sound is on but the browser has not yet allowed audio (needs a first press or key); gone after it */
.sound_wait { position: absolute; max-width: calc(100% - 2 * var(--space-3)); padding: var(--space-1) var(--space-3); background: var(--ink); color: var(--ink-on-dark); font-size: var(--text-xs); font-weight: var(--weight-label); }
.sound_wait[hidden] { display: none; }
#logout:hover, #undo:hover, #redo:hover, #retrieve_orders:hover, #sound:hover { filter: brightness(1.12) drop-shadow(0 2px 3px var(--shadow-lift)); }
#logout:active, #undo:active, #redo:active, #retrieve_orders:active, #sound:active { transform: translateY(1px); filter: drop-shadow(0 1px 2px var(--shadow-lift)); box-shadow: var(--shadow-none); }

#logout:focus-visible, #undo:focus-visible, #redo:focus-visible, #retrieve_orders:focus-visible, #sound:focus-visible { box-shadow: 0 0 0 6px var(--ink); } /* keep the ring's dark half that box-shadow: none above would drop */

/* Anchor icon (F6) for Undo and Redo: the arrow's turn direction, as a tilt. Undo counter-clockwise, Redo clockwise */
.anchor {
    display: inline-block;
    width: 1.5em;
    height: 1.5em;
    vertical-align: middle;
    background: currentColor;
    mask: url("../img/icons/anchor.webp") center / contain no-repeat;
}
#undo .anchor { rotate: -32deg; }
#redo .anchor { rotate: 32deg; }

@media (prefers-reduced-motion: reduce) {
    .menu li button, .red, .blue, .light_green, .add_button .h4, .flipper, #login, #close, .close_window, #logout, #undo, #redo, #retrieve_orders, #sound { transition: none; }
    .red:active, .blue:active, .light_green:active, .add_button:active .h4, .flipper:active, #login:active, #close:active, .close_window:active, #logout:active, #undo:active, #redo:active, #retrieve_orders:active, #sound:active { transform: none; }
}

/* COLORS */
/* Small plates (T1): rust specks (Texturelabs Metal 132, 70 %) and tarnish multiplied over brass,
   rust-red or iron, no rivets. Multiply only darkens: white is 7.37:1 or better on the worst pixel */
.light_green, .add_button .h4 {
    background:
        url("../img/textures/rust.webp") 0 0 / 400px 200px,
        url("../img/textures/tarnish.webp") 0 0 / 400px 200px,
        linear-gradient(var(--gold) 0%, var(--gold-deep) 55%, var(--brass-dark) 100%);
    background-blend-mode: multiply, multiply, normal;
    color: var(--ink-on-dark);
    box-shadow: var(--shadow-brass);
}

.red {
    background:
        url("../img/textures/rust.webp") 0 0 / 400px 200px,
        url("../img/textures/tarnish.webp") 0 0 / 400px 200px,
        linear-gradient(var(--flag-red-light) 0%, var(--flag-red) 55%, var(--rust-dark) 100%);
    background-blend-mode: multiply, multiply, normal;
    color: var(--ink-on-dark);
    box-shadow: var(--shadow-rust);
}
.headergreen {
    background-color: var(--bar-deep);
}

.darkgreen {
    background-color: var(--bar);
}
.green {
    background-color: var(--control-strong);
}
.backgroundgreen {
    background-color: var(--surface);
}
.highlightgreen{
    background-color: var(--surface-soft);
}





/* Order bars (customer and management): the rust and iron plate of the landing signs, a rivet in each upper corner of the header, and a hemp cord seam where the plate meets the ledger.
   The textures only darken the bar colour, so the text keeps 5.11:1 (heading), 5.32:1 (total label) and 6.81:1 (amount) on the lightest pixel. Only the header carries rivets */
.main_section > .selection_header, .main_section > .checkout {
    position: relative;
    background:
        url("../img/textures/rust.webp") 0 0 / 400px 200px,
        url("../img/textures/iron.webp") 0 0 / 400px 200px,
        var(--bar);
    background-blend-mode: multiply, multiply, normal;
}
.main_section > .selection_header {
    background:
        url("../img/textures/rivet.webp") left 4px top 4px / 12px 12px no-repeat,
        url("../img/textures/rivet.webp") right 4px top 4px / 12px 12px no-repeat,
        url("../img/textures/rust.webp") 0 0 / 400px 200px,
        url("../img/textures/iron.webp") 0 0 / 400px 200px,
        var(--bar);
    background-blend-mode: normal, normal, multiply, multiply, normal;
}
.main_section > .selection_header::after, .main_section > .checkout::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    height: 14px;
    background: url("../img/textures/rope.webp") 0 0 / 100% 100%;
    filter: drop-shadow(0 1px 1px var(--shadow-lift));
    pointer-events: none;
}
.main_section > .selection_header::after { bottom: 0; }
.main_section > .checkout::before { top: 0; }

/* Landing signs (T5): riveted iron plates on the storm, white 7.36:1 or better on the worst pixel.
   index.css turns "Order Your Drinks!" into brass */
.flipper {
    background:
        url("../img/textures/rivet.webp") left 3px top 3px / 12px 12px no-repeat,
        url("../img/textures/rivet.webp") right 3px top 3px / 12px 12px no-repeat,
        url("../img/textures/rivet.webp") left 3px bottom 3px / 12px 12px no-repeat,
        url("../img/textures/rivet.webp") right 3px bottom 3px / 12px 12px no-repeat,
        url("../img/textures/rust.webp") 0 0 / 400px 200px,
        url("../img/textures/iron.webp") 0 0 / 400px 200px,
        var(--bar);
    background-blend-mode: normal, normal, normal, normal, multiply, multiply, normal;
    border: 0;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-iron);
    letter-spacing: 0.04em;
}


.textRed{
    color: var(--danger-text); /* 4.86:1 or better on every sea-glass surface */
}

.alert{
    padding:2px;
    border: dashed;
    border-width: 2px;
    border-color: var(--danger-text);
}

.textDarkGreen{
    color: var(--ink-deep);
}

.textLightGreen{
    color: var(--ink-soft-on-dark);
}

/* ORDER LEDGER (T7, shared by customer and management): a ruled paper ledger (Paper 328) inside the kelp header and total bar.
   Sepia 5.72:1 or better on its darkest pixel */
.selection {
    background: url("../img/textures/paper-list.webp") 0 0 / 100% 100%, var(--paper);
    container-type: inline-size; /* narrow ledgers (a 280 px column, a phone) stack the price under the name */
}

/* one ruled row: quantity | bottle | name | price | remove (only the remove is a button) */
@keyframes row-lay { from { translate: 0 calc(-2 * var(--lift-distance)); opacity: 0; } } /* a line written on the ledger */
#drink_selection .order {
    position: relative;
    display: grid;
    grid-template-columns: auto 40px 1fr auto auto;
    grid-template-areas: "qty img name price del";
    align-items: center;
    column-gap: var(--space-2);
    height: auto;
    min-height: 64px;
    padding: 4px var(--space-2);
    color: var(--ink-sepia);
    border-bottom: 1px solid var(--rule-sepia);
}

#drink_selection .order img {
    grid-area: img;
    height: 52px;
    justify-self: center;
    transition: opacity var(--toast-close) var(--toast-ease);
}

#drink_selection .order > h4 {
    grid-area: name;
    margin: 0;
    font-weight: var(--weight-label);
}

#drink_selection .order .price {
    grid-area: price;
    white-space: nowrap;
    font-weight: var(--weight-heading);
}

/* handwritten tally, sepia 5.69:1 or better on the paper */
#drink_selection .qty {
    grid-area: qty;
    min-width: 2.2em;
    text-align: right;
    font-family: var(--font-display);
    font-weight: var(--weight-body);
    font-size: var(--text-lg);
}

/* remove: a red ink brush cross, no plate (3.38:1 or better on the paper, non-text needs 3:1); a red wash on hover and focus */
#drink_selection .order .delete {
    grid-area: del;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-round);
    background: transparent;
    color: var(--danger-text);
}

#drink_selection .order .delete .icon { width: 30px; height: 30px; }
#drink_selection .order .delete:is(:hover, :focus-visible) { background: var(--hover-danger); }

/* the row it would remove gets a brush strike, drawn left to right, and its bottle fades */
#drink_selection .order::after {
    content: "";
    position: absolute;
    left: 6px;
    right: 52px;
    top: 50%;
    height: 14px;
    margin-top: -7px;
    background: var(--danger-text);
    mask: url("../img/textures/strike.svg") left center / 0% 100% no-repeat;
    pointer-events: none;
    transition: mask-size var(--toast-close) var(--toast-ease);
}

#drink_selection .order:has(.delete:is(:hover, :focus-visible))::after {
    mask-size: 100% 100%;
    transition: mask-size var(--toast-open) var(--toast-ease);
}

#drink_selection .order:has(.delete:is(:hover, :focus-visible)) img { opacity: 0.45; }

#drink_selection .order.laid { animation: row-lay var(--lift-out) var(--toast-ease); }
@media (prefers-reduced-motion: reduce) {
    #drink_selection .order::after, #drink_selection .order img { transition: none; }
    #drink_selection .order.laid { animation: none; }
}

#drink_selection:empty {
    min-height: 160px;
}

#drink_selection:empty::before {
    content: attr(data-empty);
    display: block;
    max-width: 22ch;
    margin: var(--space-7) auto;
    text-align: center;
    font-family: var(--font-display);
    font-size: var(--text-md);
    line-height: 1.4;
    color: var(--ink-sepia);
}

@container (max-width: 400px) {
    #drink_selection .order {
        grid-template-columns: auto 40px minmax(0, 1fr) auto;
        grid-template-areas: "qty img name del" "qty img price del";
    }
    #drink_selection .order .price { justify-self: start; }
}

/* Phones: 44px touch targets for remove */
@media (max-width: 768px) {
    #drink_selection .order .delete {
        width: 44px;
        height: 44px;
    }
}

/* FEEDBACK */

/* Visually hidden; the one aria-live region lives here */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Toast: bottom centre above the footer, full width on small screens */
.toast_wrap {
    position: fixed;
    left: 16px;
    right: 16px;
    bottom: 180px; /* clears the footer row */
    display: flex;
    justify-content: center;
    pointer-events: none;
    z-index: 1000;
}

/* T9: a burnt paper note pinned with a tack; sepia 6.61:1 or better. Title and detail (F9); errors get a red wax seal and a worn red ribbon */
.toast {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    max-width: 460px;
    padding: 18px 16px 6px;
    border: 16px solid transparent;
    border-image: url("../img/textures/note.webp") 48 fill / 16px stretch; /* 9-slice: the burnt rim keeps its size */
    color: var(--ink-sepia);
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: 1.35;
    box-shadow: var(--shadow-float);
    rotate: -1deg;
}

.toast::after {
    content: "";
    position: absolute;
    top: -10px;
    left: 50%;
    width: 24px;
    height: 24px;
    margin-left: -12px;
    background: url("../img/textures/tack.webp") 0 0 / 100% 100%;
    filter: drop-shadow(0 2px 1px var(--shadow-lift));
}

.toast.is-open { pointer-events: auto; } /* a closed toast is invisible, so it must not catch clicks */

.toast_text { display: grid; gap: 2px; }
.toast_title { font-size: var(--text-md); font-weight: var(--weight-heading); }
.toast_detail:empty { display: none; }

/* Wax seal: green = done, red = error (decorative, the words carry the meaning) */
.toast_icon {
    flex: none;
    width: 44px;
    height: 44px;
    background: url("../img/textures/seal-green.webp") 0 0 / 100% 100% no-repeat;
    filter: drop-shadow(0 2px 2px var(--shadow-lift));
}

.toast.is-error { rotate: 1deg; }
.toast.is-error .toast_icon { background-image: url("../img/textures/seal-red.webp"); }

.toast_ribbon {
    display: none;
    position: absolute;
    left: -4px;
    top: -6px;
    bottom: -6px;
    width: 8px;
    background: var(--flag-red);
    mask: url("../img/textures/stamp-wear.webp") 0 0 / 60px 120px;
}
.toast.is-error .toast_ribbon { display: block; }

/* Low sea mist (F9): two feathered layers drift behind the open note, one each way; never over the text, never catching clicks */
.toast_wrap { isolation: isolate; }
.toast_wrap::before, .toast_wrap::after {
    content: "";
    position: absolute;
    z-index: -1;
    left: 50%;
    bottom: -70px;
    width: min(1000px, 150vw);
    height: 300px;
    background: url("../img/textures/mist.webp") 0 0 / 1400px 300px repeat-x;
    mask: radial-gradient(closest-side, var(--ink) 35%, transparent);
    opacity: 0;
    translate: -50% var(--toast-distance);
    pointer-events: none;
    animation: mist-drift 40s linear 0.125 forwards paused; /* 5 s of drift, then still (WCAG 2.2.2) */
    transition: opacity var(--toast-close) var(--toast-ease), translate var(--toast-close) var(--toast-ease);
}
.toast_wrap::after {
    bottom: -90px;
    height: 220px;
    background-size: 1027px 220px;
    --tile: 1027px;
    animation: mist-drift 55s linear 0.0909 reverse forwards paused;
}
.toast_wrap:has(.is-open)::before, .toast_wrap:has(.is-open)::after {
    opacity: 0.95;
    translate: -50% 0;
    animation-play-state: running;
    transition: opacity var(--toast-open) var(--toast-ease), translate var(--toast-open) var(--toast-ease);
}
.toast_wrap:has(.is-open)::after { opacity: 0.75; }
/* V12: a stamp pressed onto paper, a slip laid down */
@keyframes stamp-press { from { scale: 1.12; opacity: 0; } 40% { opacity: 1; } }
@keyframes slip-lay { from { translate: 0 calc(-1 * var(--toast-distance)); rotate: 1.5deg; opacity: 0; } 40% { opacity: 1; } }
@keyframes mist-pass { 0% { opacity: 0; } 40% { opacity: 0.95; } 100% { opacity: 0; background-position-x: 300px; } } /* a bank of mist passing (G5, G6) */
@keyframes mist-drift { to { background-position-x: var(--tile, 1400px); } } /* one tile, so the loop is seamless */
/* V12b G5: a page change through the fog. The old page sinks, a bank of mist passes (js/login.js), the new page condenses.
   Chromium only; elsewhere pages load plainly. Not under reduced motion */
@keyframes breathe-out { to { opacity: 0; filter: blur(3px); scale: 1.02; } }
@keyframes condense { from { opacity: 0; filter: var(--ghost-tint) blur(3px); } }
.mist_bank {
    position: fixed;
    inset: 0;
    z-index: 2000;
    pointer-events: none;
    opacity: 0;
    background: url("../img/textures/mist.webp") 0 50% / 900px 100% repeat-x;
    view-transition-name: mist; /* its own layer, so it stays above the page while the page fades */
    animation: mist-pass var(--fog-pass) ease-in-out;
}
/* ...and the wait for the foghorn (js/login.js depart): the page fades while a bank of mist crosses it. Opacity is not motion, so it stays under reduced motion; the bank does not */
html.departing body { opacity: 0; transition: opacity var(--depart-fade) ease-in; } /* slow at first, so the page is still half there when the mist crosses it */
html.departing .mist_bank { animation-delay: var(--depart-mist); }
@media (prefers-reduced-motion: reduce) { html.departing .mist_bank { display: none; } }
/* V12b G3: the first load of a drink list. A skull of smoke condenses out of fog (js/login.js ghostIntro), holds, and is taken back as
   card-shaped wisps appear. The cards are in the DOM from the start, hidden by the delay, and condense out of the wisps */
@keyframes ghost-in { from { opacity: 0; filter: var(--ghost-tint) blur(var(--ghost-blur)); translate: 0 6px; } 60% { opacity: 0.9; } }
@keyframes wisp-out { to { opacity: 0; filter: blur(var(--ghost-blur)); scale: 1.04; } }
@keyframes wisp-wait { from, to { opacity: 0; } }
@keyframes skull-blow { to { opacity: 0; scale: 1.2; translate: -50% -58%; } }
@keyframes card-fade { from { opacity: 0; } }
.drink_list.intro { pointer-events: none; } /* no hidden card takes a click */
.intro .drink { animation: ghost-in var(--ghost-form) var(--toast-ease) calc(var(--ghost-wait) + var(--i, 0) * var(--ghost-stagger)) backwards; }
.intro_fx { position: absolute; inset: 0; pointer-events: none; }
.wisp {
    position: absolute;
    border-radius: var(--radius-md);
    opacity: 0.45;
    --tile: 200px;
    background: url("../img/textures/mist.webp") 0 0 / 600px 100% repeat-x;
    -webkit-mask: var(--paper) 0 0 / 100% 100%; /* the shape of the card it will become */
    mask: var(--paper) 0 0 / 100% 100%;
    animation: wisp-wait var(--ghost-blow) linear, mist-drift var(--fog-pass) linear var(--ghost-blow) forwards, wisp-out var(--ghost-form) var(--toast-ease) calc(var(--ghost-wait) + var(--i, 0) * var(--ghost-stagger)) forwards;
}
/* The skull is the project's skull-and-crossbones drawing: its white fill shows, its black lines are gaps (luminance mask), worn through by the stamp-wear grit.
   The #smoke filter is on the parent, and the masks are on ::before, because CSS masks after filtering */
.skull {
    position: absolute;
    left: 50%;
    top: 50%;
    width: min(70%, 260px);
    aspect-ratio: 510 / 490;
    translate: -50% -50%;
    z-index: 2;
    filter: url(#smoke) blur(0.6px);
    opacity: 0.85;
    animation: skull-blow var(--fog-pass) ease-in var(--ghost-blow) forwards;
}
.skull::before {
    content: "";
    position: absolute;
    inset: 0;
    background: url("../img/textures/tarnish.webp") 0 0 / 200px 100px, url("../img/textures/mist.webp") 0 0 / 300px 100%, var(--bone);
    background-blend-mode: multiply, screen, normal; /* old bone: yellowed, stained by tarnish */
    -webkit-mask: url("../img/skull.svg") center / contain no-repeat luminance, url("../img/textures/stamp-wear.webp") 0 0 / 200px 100px;
    -webkit-mask-composite: source-in;
    mask: url("../img/skull.svg") center / contain no-repeat luminance, url("../img/textures/stamp-wear.webp") 0 0 / 200px 100px;
    mask-composite: intersect;
}
/* V12b G4: a tab switch. The leaving cards and the echoes are loose copies in this layer (js/login.js ghostSwap), so none takes a click.
   It is cut to the list's height, so a copy at an old seat cannot stretch the scroll */
.swap_fx { position: absolute; left: 0; right: 0; top: 0; overflow: clip; pointer-events: none; }
.swap_fx .drink { position: absolute; margin: 0; }
@media (prefers-reduced-motion: reduce) {
    .intro .drink { animation: card-fade var(--lift-out) backwards; }
}
@media (prefers-reduced-motion: no-preference) {
    @view-transition { navigation: auto; types: page; }
    :active-view-transition-type(page)::view-transition-old(root) { animation: breathe-out var(--page-out) ease-in forwards; mix-blend-mode: normal; }
    :active-view-transition-type(page)::view-transition-new(root) { animation: condense var(--page-in) var(--toast-ease) var(--page-delay) backwards; mix-blend-mode: normal; }
    ::view-transition-new(mist) { animation: none; } /* the bank fades itself */
}

@media (max-width: 768px) {
    .toast_wrap { bottom: 16px; }
    .toast { max-width: none; flex: 1; }
}

/* transitions-dev: Toast open / close */
.t-toast {
  opacity: 0;
  transform: translateY(var(--toast-distance)) scale(var(--toast-scale));
  filter: blur(var(--toast-blur));
  will-change: transform, opacity, filter;
  transition:
    opacity var(--toast-close) var(--toast-ease),
    transform var(--toast-close) var(--toast-ease),
    filter var(--toast-close) var(--toast-ease);
}
.t-toast.is-open {
  opacity: 1;
  transform: translateY(0) scale(1);
  filter: blur(0);
  transition:
    opacity var(--toast-open) var(--toast-ease),
    transform var(--toast-open) var(--toast-ease),
    filter var(--toast-open) var(--toast-ease);
}

@media (prefers-reduced-motion: reduce) {
  .t-toast, .toast_wrap::before, .toast_wrap::after { transition: none !important; animation: none !important; }
}
