/* ---------- The app's one drawer (DESIGN.md, "Drawers") ----------
   Every dialog in the app is a drawer: a native <dialog class="sh-drawer">
   opened with showModal(), sliding in from the right at full height.

   Structure (all parts optional except the dialog):
     <dialog class="sh-drawer [sh-drawer--narrow|--wide]" aria-labelledby="x-title">
       <header class="sh-drawer-head">
         <h2 class="sh-drawer-title" id="x-title">Title</h2>
         <p class="sh-drawer-lede">One line of context.</p>
         <button type="button" class="sh-drawer-x" data-drawer-close aria-label="Close">×</button>
       </header>
       <div class="sh-drawer-body"> … scrolls … </div>
       <footer class="sh-drawer-foot"> secondary … primary (last, filled) </footer>
     </dialog>

   Stacking: a drawer opened while another is open sits on top; the one
   below slides left by --drawer-peek so its edge shows. Esc or × closes the
   top one only and the one below comes back (native <dialog> behaviour;
   js/drawer_stack.js sets data-drawer-level and --drawer-depth).
   Widths: narrow 440px (short forms), default 640px, wide 880px (tables). */

html body.d1-page dialog.sh-drawer {
    --drawer-w: 640px;
    --drawer-peek: 28px;
    --drawer-depth: 0;
    position: fixed;
    inset: 0 0 0 auto;
    box-sizing: border-box;
    width: min(var(--drawer-w), 100vw);
    max-width: 100vw;
    height: 100vh;
    height: 100dvh;
    max-height: none;
    margin: 0;
    padding: 0;
    border: 0;
    border-left: 1px solid var(--d1-line);
    border-radius: 0;
    background: var(--d1-card, var(--d1-bg));
    color: var(--d1-ink);
    box-shadow: -24px 0 60px -20px rgba(15, 23, 42, .35);
    overflow: hidden;
    transform: translateX(calc(-1 * var(--drawer-peek) * var(--drawer-depth)));
    transition: transform .22s cubic-bezier(.2, .8, .2, 1);
}
html body.d1-page dialog.sh-drawer:not([open]) { display: none; }
html body.d1-page dialog.sh-drawer[open] { display: flex; flex-direction: column; animation: sh-drawer-in .24s cubic-bezier(.2, .8, .2, 1); }
html body.d1-page dialog.sh-drawer.sh-drawer--narrow { --drawer-w: 440px; }
html body.d1-page dialog.sh-drawer.sh-drawer--wide { --drawer-w: 880px; }
@keyframes sh-drawer-in { from { translate: 40px 0; opacity: 0; } }

/* Resize from the left edge (js/drawer_stack.js adds the handle): a thin
   strip that shows a blue line and a grip on hover; drag, or ← → when
   focused; double-click resets. Hidden on a phone (the drawer is full width). */
html body.d1-page .sh-drawer-grab { position: absolute; z-index: 5; top: 0; bottom: 0; left: 0; width: 10px; cursor: ew-resize; touch-action: none; outline: none; }
html body.d1-page .sh-drawer-grab::before { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 2px; background: transparent; transition: background .15s; }
html body.d1-page .sh-drawer-grab::after { content: ""; position: absolute; top: 50%; left: 3px; width: 4px; height: 40px; margin-top: -20px; border-radius: 4px; background: var(--d1-line-2); opacity: .7; transition: opacity .15s, background .15s; }
html body.d1-page .sh-drawer:hover > .sh-drawer-grab::after, html body.d1-page .sh-resizable:hover > .sh-drawer-grab::after { opacity: 1; }
html body.d1-page .sh-resizable.is-resizing { user-select: none; }
html body.d1-page .sh-drawer-grab:hover::before, html body.d1-page .sh-drawer-grab:focus-visible::before, html body.d1-page .sh-drawer.is-resizing > .sh-drawer-grab::before { background: var(--d1-blue); }
html body.d1-page .sh-drawer-grab:hover::after, html body.d1-page .sh-drawer-grab:focus-visible::after, html body.d1-page .sh-drawer.is-resizing > .sh-drawer-grab::after { background: var(--d1-blue); opacity: 1; }
html body.d1-page dialog.sh-drawer.is-resizing { transition: none; user-select: none; }
@media (max-width: 640px) { html body.d1-page .sh-drawer-grab { display: none; } }

html body.d1-page dialog.sh-drawer::backdrop { background: rgba(15, 23, 42, .28); }
/* A drawer on top of another only lightly dims the one below. */
html body.d1-page dialog.sh-drawer:not([data-drawer-level="1"])::backdrop { background: rgba(15, 23, 42, .14); }

/* Parts. A drawer whose content has its own wrapper can skip them; the
   wrapper should then be display:flex column with a scrolling middle. */
html body.d1-page .sh-drawer-head {
    flex: none;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 4px 16px;
    align-items: start;
    padding: 28px 32px 20px;
    border-bottom: 1px solid var(--d1-line);
}
html body.d1-page dialog.sh-drawer .sh-drawer-title {
    grid-column: 1;
    margin: 0;
    font: 600 24px/1.15 var(--sans, "Bricolage Grotesque", system-ui, sans-serif);
    letter-spacing: -.01em;
    color: var(--d1-ink);
    text-transform: none;
}
html body.d1-page .sh-drawer-lede { grid-column: 1; margin: 0; color: var(--d1-ink-2); font-size: 14.5px; line-height: 1.45; }
/* A close or remove ×, drawn, not typed (DESIGN.md "Icons are drawn"): a text
   glyph sits where each font puts it (on the baseline, at the font's maths
   axis), so it is never quite centred and moves between Mac and Windows
   fonts. Any button with .sh-x (and every .sh-drawer-x) hides its "×" text,
   kept as a no-CSS fallback, and two 2px bars pinned to the exact centre of
   the box make the cross. --sh-x sets the bar length (default 12px). */
html body.d1-page :is(.sh-x, .sh-drawer-x) {
    position: relative;
    font-size: 0;
    line-height: 0;
}
html body.d1-page :is(.sh-x, .sh-drawer-x)::before,
html body.d1-page :is(.sh-x, .sh-drawer-x)::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--sh-x, 12px);
    height: 2px;
    border-radius: 1px;
    background: currentColor;
    transform: translate(-50%, -50%) rotate(45deg);
}
html body.d1-page :is(.sh-x, .sh-drawer-x)::after { transform: translate(-50%, -50%) rotate(-45deg); }

html body.d1-page .sh-drawer-x {
    --sh-x: 16px;
    grid-column: 2;
    grid-row: 1 / span 2;
    display: block;
    box-sizing: border-box;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--d1-line);
    border-radius: 8px;
    background: var(--d1-card, #fff);
    color: var(--d1-ink-2);
    cursor: pointer;
}
html body.d1-page .sh-drawer-x:hover { background: var(--d1-paper); color: var(--d1-ink); }
html body.d1-page .sh-drawer-body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 20px 32px 28px; }
html body.d1-page .sh-drawer-foot {
    flex: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    padding: 16px 32px;
    border-top: 1px solid var(--d1-line);
    background: var(--d1-card, #fff);
}
/* A part a page hides for one step (a footer shown only on a confirm step). */
html body.d1-page :is(.sh-drawer-head, .sh-drawer-body, .sh-drawer-foot)[hidden] { display: none; }
/* A note or error in the footer sits on the left, buttons on the right. */
html body.d1-page .sh-drawer-foot > .sh-drawer-note { margin: 0 auto 0 0; color: var(--d1-muted); font-size: 13px; }

@media (max-width: 640px) {
    html body.d1-page dialog.sh-drawer { --drawer-peek: 0px; width: 100vw; border-left: 0; }
    html body.d1-page .sh-drawer-head { padding: 20px 16px 16px; }
    html body.d1-page .sh-drawer-body { padding: 16px; }
    html body.d1-page .sh-drawer-foot { padding: 12px 16px; }
}
@media (prefers-reduced-motion: reduce) {
    html body.d1-page dialog.sh-drawer, html body.d1-page dialog.sh-drawer[open] { animation: none; transition: none; }
}

/* ---------- Press twice to confirm (button_feedback.js, confirmTwice) ----------
   A small yes/no ("Delete this rule set?") never opens a drawer: the first
   press arms the button, which says "Click again to …" over its own label
   (so it never changes size); a second press within a few seconds does it. */
html body.d1-page .btn.is-armed { position: relative; }
html body.d1-page .btn.is-armed::after {
    content: attr(data-armed-text);
    position: absolute; inset: -1px; display: grid; place-items: center; padding: 0 6px;
    border-radius: inherit; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    font-weight: 600; pointer-events: none;
    color: #fff; background: var(--red, #c62f2f); border: 1px solid var(--red, #c62f2f);
    animation: d1-done-in .16s ease-out;
}
