/*
 * w/copy layout and components.
 * Motion is transform/opacity only; tokens.css zeroes durations under
 * prefers-reduced-motion, so every transition here already respects it.
 */

/* ---------- reset ---------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: var(--fs-base);
  line-height: var(--line-height);
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}

h1,
h2,
h3,
p {
  margin: 0;
}

button {
  font: inherit;
  color: inherit;
}

textarea {
  font: inherit;
  color: inherit;
}

a {
  color: var(--accent);
}

/* ---------- icons ---------- */

.wc-icon {
  width: 20px;
  height: 20px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.wc-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* ---------- buttons ---------- */

.wc-iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: none;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease);
}

.wc-iconbtn:hover {
  background: var(--surface-2);
  color: var(--text);
}

.wc-iconbtn:active {
  transform: scale(0.92);
}

.wc-iconbtn--sm {
  width: 32px;
  height: 32px;
}

.wc-iconbtn--sm .wc-icon {
  width: 16px;
  height: 16px;
}

.wc-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease);
}

.wc-btn .wc-icon {
  width: 16px;
  height: 16px;
}

.wc-btn:hover {
  background: var(--surface-2);
  border-color: var(--text-muted);
}

.wc-btn:active {
  transform: scale(0.97);
}

.wc-btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

.wc-btn--primary:hover {
  background: var(--accent);
  filter: brightness(1.06);
}

.wc-btn--block {
  width: 100%;
  justify-content: center;
}

button:focus-visible,
input:focus-visible,
textarea:focus-visible,
a:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- top bar ---------- */

.wc-topbar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) max(var(--space-4), calc((100% - 640px) / 2));
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.wc-stackname {
  flex: 1;
  min-width: 0;
  text-align: center;
  font-size: var(--fs-md);
  font-weight: 700;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  position: relative;
}

.wc-stackname::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: var(--space-2);
  border-radius: var(--radius-full);
  background: var(--accent);
  vertical-align: middle;
}

/* ---------- main / stack ---------- */

.wc-main {
  flex: 1;
  padding: var(--space-4) max(var(--space-4), calc((100% - 640px) / 2))
    calc(var(--space-7) * 2.6);
}

.wc-stack {
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--card-gap);
}

.wc-add {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-3);
  border: 1.5px dashed var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--text-muted);
  font-weight: 600;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
    background var(--dur-fast) var(--ease);
}

.wc-add:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
}

/* ---------- piece card ---------- */

.wc-piece {
  background: var(--surface);
  border: 1px solid var(--card-border-color);
  border-radius: var(--radius);
  box-shadow: var(--card-shadow);
  padding: var(--card-pad);
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease),
    opacity var(--dur) var(--ease);
}

.wc-piece[data-enabled="false"] {
  opacity: 0.55;
}

.wc-piece.wc-piece--dragging {
  box-shadow: var(--shadow-lg);
  z-index: 2;
  /* Follows the pointer 1:1 — see the "drag to reorder" section below for
     --wc-drag-y and why this overrides the base transition. */
  transition: none;
  transform: translate3d(0, var(--wc-drag-y, 0px), 0);
  cursor: grabbing;
}

.wc-piece__bar {
  display: flex;
  align-items: center;
  gap: var(--bar-gap);
}

/* switch */

.wc-switch {
  display: inline-flex;
  flex: none;
  cursor: pointer;
}

.wc-switch input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.wc-switch__track {
  position: relative;
  width: 36px;
  height: 22px;
  border-radius: var(--radius-full);
  background: var(--border);
  transition: background var(--dur-fast) var(--ease);
}

.wc-switch__thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: var(--radius-full);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: transform var(--dur-fast) var(--ease);
}

.wc-switch input:checked + .wc-switch__track {
  background: var(--accent);
}

.wc-switch input:checked + .wc-switch__track .wc-switch__thumb {
  transform: translateX(14px);
}

.wc-switch input:focus-visible + .wc-switch__track {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* piece label + kind chip */

.wc-piece__label {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-1);
  border: none;
  background: transparent;
  text-align: left;
  cursor: pointer;
  border-radius: var(--radius-sm);
}

.wc-piece__label:hover {
  background: var(--surface-2);
}

.wc-piece__label--static {
  cursor: default;
}

.wc-piece__label--static:hover {
  background: transparent;
}

.wc-kind {
  flex: none;
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
}

.wc-piece[data-kind="header"] .wc-kind {
  color: var(--kind-header);
  background: color-mix(in srgb, var(--kind-header) 16%, var(--surface-2));
}

.wc-piece[data-kind="footer"] .wc-kind {
  color: var(--kind-footer);
  background: color-mix(in srgb, var(--kind-footer) 16%, var(--surface-2));
}

.wc-piece[data-kind="text"] .wc-kind {
  color: var(--kind-text);
  background: color-mix(in srgb, var(--kind-text) 16%, var(--surface-2));
}

.wc-piece[data-kind="clipboard"] .wc-kind {
  color: var(--kind-clipboard);
  background: var(--surface-2);
}

.wc-piece__variantname {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.wc-piece__label[aria-expanded="true"] .wc-piece__variantname {
  color: var(--text);
}

/* textarea */

.wc-piece__text {
  display: block;
  width: 100%;
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-1);
  border: none;
  background: transparent;
  resize: none;
  field-sizing: content;
  min-height: 2.6em;
  color: var(--text);
}

.wc-piece__text::placeholder {
  color: var(--text-muted);
}

/* clipboard slot */

.wc-piece--clipboard {
  border-style: dashed;
  border-width: 1.5px;
  border-color: var(--border);
  background: color-mix(in srgb, var(--kind-clipboard) 5%, var(--surface));
  box-shadow: none;
}

.wc-clipboard-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-3);
  color: var(--text-muted);
  text-align: center;
}

/* W7: hidden while the opt-in preview is on (piece-card.js's
   `fillClipboardPreview` toggles this). Needed explicitly, same reasoning
   as `.wc-variants[hidden]` above: an author rule's `display` always beats
   the UA stylesheet's `[hidden] { display: none }`. */
.wc-clipboard-slot[hidden] {
  display: none;
}

.wc-clipboard-slot__icon {
  width: 28px;
  height: 28px;
  color: var(--kind-clipboard);
}

.wc-clipboard-slot__caption {
  font-size: var(--fs-sm);
  font-weight: 600;
}

/* drag handle */

.wc-handle {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 40px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: grab;
  touch-action: none;
  border-radius: var(--radius-sm);
}

.wc-handle:hover {
  color: var(--text);
  background: var(--surface-2);
}

.wc-handle:active {
  cursor: grabbing;
}

.wc-handle .wc-icon {
  width: 18px;
  height: 18px;
  stroke: none;
  fill: currentColor;
}

/* ---------- variants ---------- */

.wc-variants {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.wc-variant {
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
}

.wc-variant:hover {
  background: var(--surface-2);
}

.wc-variantlist {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.wc-variant__radio {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
}

.wc-variant__radio input {
  accent-color: var(--accent);
  width: 16px;
  height: 16px;
  flex: none;
}

.wc-variant__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-sm);
}

.wc-variant__rename {
  flex: none;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.wc-variant__rename:hover {
  color: var(--text);
  background: var(--surface);
}

.wc-variants__add {
  align-self: flex-start;
  margin-top: var(--space-1);
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  border: none;
  background: transparent;
  color: var(--accent);
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.wc-variants__add:hover {
  background: var(--accent-soft);
}

.wc-variants__add .wc-icon {
  width: 16px;
  height: 16px;
}

/* ---------- action bar ---------- */

.wc-actionbar {
  position: sticky;
  bottom: 0;
  z-index: var(--z-actionbar);
  display: flex;
  /* Column, not row: the pile strip (W6) sits above the action row, and W5
     adds an optional hint line below it, so this bar stacks its children and
     centers them horizontally instead of centering a single row. */
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4) calc(var(--space-3) + env(safe-area-inset-bottom));
  background: linear-gradient(to top, var(--bg) 60%, transparent);
}

/* Holds w/copy and i/copy side by side. `align-items: stretch` (flex's
   default) is what keeps the two buttons the same height even though their
   font sizes differ slightly — see the W6 section below. */
.wc-actionrow {
  display: flex;
  width: 100%;
  max-width: 640px;
  gap: var(--space-3);
}

.wc-action {
  flex: 1.7 1 0;
  /* Was a <button>; is a contenteditable <div> as of W5 (see below), which
     doesn't center text by default the way a button does. */
  display: block;
  text-align: center;
  padding: var(--space-4);
  border: none;
  border-radius: var(--radius-lg);
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: var(--fs-lg);
  font-weight: 800;
  letter-spacing: -0.01em;
  box-shadow: var(--shadow-md);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease),
    filter var(--dur-fast) var(--ease);
}

.wc-action:hover {
  filter: brightness(1.05);
  box-shadow: var(--shadow-lg);
}

.wc-action:active {
  transform: scale(0.98);
}

/* ---------- side panel ---------- */

.wc-panel[hidden] {
  display: none;
}

.wc-panel {
  position: fixed;
  inset: 0;
  z-index: var(--z-panel);
}

.wc-panel__backdrop {
  position: absolute;
  inset: 0;
  background: var(--backdrop);
  opacity: 1;
  transition: opacity var(--dur) var(--ease);
}

@starting-style {
  .wc-panel:not([hidden]) .wc-panel__backdrop {
    opacity: 0;
  }
}

.wc-panel__sheet {
  position: absolute;
  inset: 0 auto 0 0;
  width: min(320px, 84vw);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  transform: translateX(0);
  transition: transform var(--dur) var(--ease);
}

@starting-style {
  .wc-panel:not([hidden]) .wc-panel__sheet {
    transform: translateX(-100%);
  }
}

.wc-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.wc-panel__header h2 {
  font-size: var(--fs-md);
  font-weight: 700;
}

.wc-stacklist {
  flex: 1;
  overflow-y: auto;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.wc-stackrow {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text);
}

.wc-stackrow:hover {
  background: var(--surface-2);
}

.wc-stackrow[data-active="true"] {
  background: var(--accent-soft);
}

.wc-stackrow__dot {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: var(--radius-full);
  background: var(--accent);
}

.wc-stackrow[data-accent="green"] .wc-stackrow__dot {
  background: var(--accent-green);
}
.wc-stackrow[data-accent="orange"] .wc-stackrow__dot {
  background: var(--accent-orange);
}
.wc-stackrow[data-accent="blue"] .wc-stackrow__dot {
  background: var(--accent-blue);
}
.wc-stackrow[data-accent="purple"] .wc-stackrow__dot {
  background: var(--accent-purple);
}
.wc-stackrow[data-accent="pink"] .wc-stackrow__dot {
  background: var(--accent-pink);
}
.wc-stackrow[data-accent="teal"] .wc-stackrow__dot {
  background: var(--accent-teal);
}
.wc-stackrow[data-accent="red"] .wc-stackrow__dot {
  background: var(--accent-red);
}
.wc-stackrow[data-accent="yellow"] .wc-stackrow__dot {
  background: var(--accent-yellow);
}

.wc-stackrow__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-base);
  font-weight: 600;
}

.wc-stackrow__check {
  flex: none;
  width: 16px;
  height: 16px;
  color: var(--accent);
}

.wc-stackrow:not([data-active="true"]) .wc-stackrow__check {
  visibility: hidden;
}

/* ---------- dialogs ---------- */

dialog {
  color: var(--text);
  background: var(--surface);
}

.wc-settings,
.wc-expand,
.wc-paste,
.wc-qr {
  padding: 0;
  border: none;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  opacity: 1;
  transform: scale(1) translateY(0);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}

@starting-style {
  .wc-settings[open],
  .wc-expand[open],
  .wc-paste[open],
  .wc-qr[open] {
    opacity: 0;
    transform: scale(0.96) translateY(10px);
  }
}

.wc-settings::backdrop,
.wc-expand::backdrop,
.wc-paste::backdrop,
.wc-qr::backdrop {
  background: var(--backdrop);
  opacity: 1;
  transition: opacity var(--dur) var(--ease);
}

@starting-style {
  .wc-settings[open]::backdrop,
  .wc-expand[open]::backdrop,
  .wc-paste[open]::backdrop,
  .wc-qr[open]::backdrop {
    opacity: 0;
  }
}

.wc-dialog {
  display: flex;
  flex-direction: column;
  max-height: 85vh;
  width: min(480px, 92vw);
}

.wc-dialog__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--border);
}

.wc-dialog__header h2 {
  font-size: var(--fs-md);
  font-weight: 700;
}

.wc-dialog__body {
  overflow-y: auto;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.wc-settings__section h3 {
  margin: 0 0 var(--space-3);
  font-size: var(--fs-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

.wc-radiogroup {
  border: none;
  margin: 0 0 var(--space-4);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.wc-radiogroup:last-child {
  margin-bottom: 0;
}

.wc-radiogroup legend {
  width: 100%;
  margin-bottom: var(--space-2);
  padding: 0;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-muted);
}

.wc-radiogroup label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.wc-radiogroup label:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--text);
}

.wc-radiogroup input {
  accent-color: var(--accent);
}

.wc-settings__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
}

.wc-settings__row:last-child {
  border-bottom: none;
}

.wc-settings__row--stack {
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-2);
}

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

.wc-settings__import {
  width: 100%;
  min-height: 5em;
  padding: var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  resize: vertical;
}

.wc-settings__errors {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent-red) 12%, var(--surface-2));
  color: var(--accent-red);
  font-size: var(--fs-xs);
  white-space: pre-wrap;
}

.wc-settings__about {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

/* expand dialog: fill-screen on narrow, large centered sheet on wide */

.wc-expand {
  inset: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  max-width: 100vw;
  max-height: 100vh;
  max-height: 100dvh;
  border-radius: 0;
}

.wc-expand__inner {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.wc-expand__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(var(--space-3) + env(safe-area-inset-top)) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--border);
}

.wc-expand__text {
  flex: 1;
  border: none;
  padding: var(--space-4);
  resize: none;
  background: transparent;
  color: var(--text);
  font-size: var(--fs-md);
  line-height: var(--line-height);
}

@media (min-width: 720px) {
  .wc-expand {
    margin: auto;
    width: min(720px, 90vw);
    height: min(640px, 85vh);
    max-width: 90vw;
    max-height: 85vh;
    border-radius: var(--radius-lg);
  }
}

/* paste fallback */

.wc-paste__inner {
  display: flex;
  flex-direction: column;
  width: min(480px, 92vw);
  max-height: 85vh;
}

.wc-paste__hint {
  padding: 0 var(--space-4);
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.wc-paste__text {
  margin: var(--space-4);
  margin-top: var(--space-3);
  min-height: 8em;
  padding: var(--space-3);
  border: 1.5px dashed var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--text);
  resize: vertical;
}

/* ---------- toast ---------- */

.wc-toast {
  position: fixed;
  left: 50%;
  top: max(var(--space-4), env(safe-area-inset-top));
  transform: translate(-50%, -16px);
  z-index: var(--z-toast);
  width: min(420px, calc(100vw - var(--space-6)));
  opacity: 0;
  pointer-events: none;
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}

.wc-toast[hidden] {
  display: none;
}

.wc-toast--visible {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}

.wc-toast__body {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  border-radius: var(--radius);
  background: var(--text);
  color: var(--bg);
  box-shadow: var(--shadow-lg);
}

.wc-toast__message {
  flex: 1;
  min-width: 0;
  font-size: var(--fs-sm);
  font-weight: 600;
}

.wc-toast__action {
  flex: none;
  border: none;
  background: transparent;
  color: inherit;
  font-size: var(--fs-sm);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
  opacity: 0.9;
}

.wc-toast__action:hover {
  opacity: 1;
  background: rgba(255, 255, 255, 0.12);
}

.wc-toast__close {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: inherit;
  opacity: 0.7;
  border-radius: var(--radius-full);
  cursor: pointer;
}

.wc-toast__close:hover {
  opacity: 1;
  background: rgba(255, 255, 255, 0.12);
}

.wc-toast__close .wc-icon {
  width: 16px;
  height: 16px;
}

.wc-toast--success .wc-toast__body {
  background: var(--accent-green);
  color: var(--accent-green-contrast);
}

.wc-toast--error .wc-toast__body {
  background: var(--accent-red);
  color: var(--accent-red-contrast);
}

/* bottom placement at wider viewports */
@media (min-width: 640px) {
  .wc-toast {
    top: auto;
    bottom: calc(var(--space-5) + env(safe-area-inset-bottom));
    transform: translate(-50%, 16px);
  }

  .wc-toast--visible {
    transform: translate(-50%, 0);
  }
}

/* ==========================================================================
   Added in W2A: add-piece popover
   ========================================================================== */

.wc-addwrap {
  position: relative;
}

.wc-addmenu {
  position: absolute;
  z-index: var(--z-panel);
  bottom: calc(100% + var(--space-2));
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  opacity: 1;
  transform: translateY(0) scale(1);
  transform-origin: bottom center;
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}

.wc-addmenu[hidden] {
  display: none;
}

@starting-style {
  .wc-addmenu:not([hidden]) {
    opacity: 0;
    transform: translateY(6px) scale(0.98);
  }
}

.wc-addmenu__item {
  padding: var(--space-3);
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}

.wc-addmenu__item:hover {
  background: var(--surface-2);
}

/* ==========================================================================
   Added in W2A: inline variant rename input
   ========================================================================== */

.wc-variant__rename-input {
  flex: 1;
  min-width: 0;
  padding: 2px var(--space-1);
  border: none;
  border-bottom: 1.5px solid var(--accent);
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-size: var(--fs-sm);
}

.wc-variant__radio--renaming {
  flex: none;
}

/* Defect fix: an author rule's `display` always beats the UA stylesheet's
   `[hidden] { display: none }`, regardless of specificity — so `.wc-variants`
   (which sets `display: flex` above) needs its own [hidden] override or the
   collapsed variants region never actually collapses. */
.wc-variants[hidden] {
  display: none;
}

/* ==========================================================================
   Added in W2B: side panel (stacks list, delete, top bar rename) and
   settings (disabled share/QR, import file input)
   ========================================================================== */

.wc-stackrow {
  outline-offset: -2px;
}

/* Delete lives inside the row alongside the switch-stack tap target; give it
   a consistent gap from the check mark whether or not the check is visible. */
.wc-stackrow > .wc-iconbtn {
  margin-left: var(--space-1);
  flex: none;
}

/* Inline rename input for the top bar stack title, matching the accent
   underline treatment of the variant rename input in piece cards. */
.wc-stackname {
  cursor: pointer;
}

.wc-stackname--renaming {
  cursor: text;
}

.wc-stackname__input {
  width: 100%;
  max-width: 100%;
  padding: 0;
  border: none;
  border-bottom: 1.5px solid var(--accent);
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-weight: 700;
  text-align: center;
}

/* Settings: a disabled action button (share link / QR, "Coming next") reads
   as inert rather than merely muted. */
.wc-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.wc-btn:disabled:hover {
  background: var(--surface);
  border-color: var(--border);
}

/* ==========================================================================
   Added in W3A: drag to reorder (drag.js)

   Everything here is transform-only, on purpose: `.wc-piece` (above) already
   transitions `transform`, so a sibling gaining/losing `--shift-up`/
   `--shift-down` animates for free, on the compositor, with no layout or
   paint — and goes instant under `prefers-reduced-motion` because
   `tokens.css` zeroes `--dur` there, with nothing extra needed here. The
   dragged card itself (`.wc-piece--dragging`, above) opts out of that
   transition so it can follow the pointer without lag.

   `--wc-drag-y` and `--wc-shift-h` are custom properties written by drag.js
   via `style.setProperty`/`removeProperty` — a CSSOM write, not a
   stylesheet or a `style` attribute, so the page's `style-src` CSP directive
   does not apply to it (confirmed with a `securitypolicyviolation` listener
   during manual testing: none fires).
   ========================================================================== */

.wc-piece--shift-down {
  transform: translate3d(0, var(--wc-shift-h, 0px), 0);
}

.wc-piece--shift-up {
  transform: translate3d(0, calc(-1 * var(--wc-shift-h, 0px)), 0);
}

/* Visually hidden but reachable by assistive tech — used for drag.js's
   keyboard-reorder live-region announcement. Same clip technique as the
   switch's native checkbox above. */
.wc-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ==========================================================================
   Added in W3B: share link and QR (settings.js "Share this stack" row and
   the dedicated QR dialog). The disabled-button rule from W2B, above, now
   applies to nothing — the share/QR buttons lost their `disabled` attribute
   — but is left in place as a plain :disabled selector, harmless if another
   button ever needs it.
   ========================================================================== */

/* A dedicated dialog, not nested in Settings: showModal() dialogs render in
   the browser's top layer, so opening one from inside another isn't
   possible anyway — settings.js closes Settings before opening this one
   (see its closeSettingsDialog/closeQrDialog comments). Sized like
   .wc-paste__inner (a plain content wrapper; the <dialog> itself only
   carries the shared reset above, matching every other dialog here). */
.wc-qr__inner {
  display: flex;
  flex-direction: column;
  width: min(360px, 92vw);
  max-height: 85vh;
}

.wc-qr__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  overflow-y: auto;
}

/* The QR itself needs a true white quiet zone to scan reliably regardless
   of the app's theme — canvas pixels are drawn white/black directly by
   qr.js's drawQR, so this just keeps the card around it white too, with no
   dark-mode override. */
.wc-qr__canvas {
  width: 100%;
  max-width: 260px;
  height: auto;
  border-radius: var(--radius-sm);
  background: #ffffff;
}

.wc-qr__url {
  margin: 0;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: var(--fs-xs);
  word-break: break-all;
  text-align: center;
}

/* ==========================================================================
   Added in W6: i/copy — the second, secondary action button; the pile
   strip and its preview.

   Design intent (docs/tasks/w6-icopy-stack.md): w/copy stays the one
   saturated, dominant control. i/copy sits beside it, same corner radius
   and height (via .wc-actionrow's flex `stretch`) so the pair reads as one
   family, but built entirely from --accent-soft/--accent — a tonal
   treatment, never the solid --accent fill w/copy uses — plus a narrower
   flex share (1 vs w/copy's 1.7) and a smaller font size. Three signals
   (fill weight, size, width), not one, keep it legibly secondary in every
   theme and density without needing to mute it into illegibility.
   ========================================================================== */

.wc-action--pile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  flex: 1 1 0;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: var(--fs-md);
  font-weight: 700;
}

.wc-action--pile .wc-icon {
  width: 18px;
  height: 18px;
}

.wc-action--pile:hover {
  filter: none;
  background: color-mix(in srgb, var(--accent) 18%, var(--accent-soft));
  box-shadow: var(--shadow-md);
}

.wc-action--pile:active {
  transform: scale(0.98);
}

/* The strip: "N pieces stacked ... Clear". Present only while the pile is
   non-empty — main.js's renderPileStrip toggles [hidden]. Tonal, at the
   active stack's accent, like the piece "Add variant" and radio-chip
   treatments elsewhere in this file. */
.wc-pilestrip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  max-width: 640px;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius);
  background: var(--accent-soft);
}

.wc-pilestrip[hidden] {
  display: none;
}

.wc-pilestrip__toggle {
  display: inline-flex;
  align-items: center;
  min-width: 0;
  gap: var(--space-2);
  border: none;
  background: transparent;
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}

.wc-pilestrip__toggle:hover {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.wc-pilestrip__icon {
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--accent);
}

.wc-pilestrip__toggle span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wc-pilestrip__chevron {
  width: 14px;
  height: 14px;
  flex: none;
  color: var(--text-muted);
  transition: transform var(--dur-fast) var(--ease);
}

.wc-pilestrip__toggle[aria-expanded="true"] .wc-pilestrip__chevron {
  transform: rotate(180deg);
}

.wc-pilestrip__clear {
  flex: none;
  border: none;
  background: transparent;
  color: var(--accent);
  font-size: var(--fs-xs);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}

.wc-pilestrip__clear:hover {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

/* The preview: revealed by tapping the strip's count, per the brief's "keep
   it inside the existing single-screen model; a small expanding region,
   not a dialog." Same starting-style entrance pattern as .wc-addmenu. */
.wc-pilepreview {
  width: 100%;
  max-width: 640px;
  max-height: 40vh;
  overflow-y: auto;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
  opacity: 1;
  transform: translateY(0);
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}

.wc-pilepreview[hidden] {
  display: none;
}

@starting-style {
  .wc-pilepreview:not([hidden]) {
    opacity: 0;
    transform: translateY(-6px);
  }
}

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

.wc-pilepreview__item {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
}

.wc-pilepreview__index {
  flex: none;
  min-width: 1.4em;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-xs);
}

.wc-pilepreview__text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
}

/* ==========================================================================
   Added in W5: clipboard streamline. Both action buttons (.wc-action, above
   — w/copy and, with .wc-action--pile layered on for i/copy) became
   contenteditable <div>s so either can double as a paste target on devices
   that can't read the clipboard (spec §4.4/§6) — see main.js's
   handleActionPaste and updateActionUI. The rules below keep them looking
   and behaving like plain buttons rather than text fields: no visible
   selection/callout chrome of ours, no accidental scroll, same look in
   every label state ("w/copy"/"Paste to w/copy", "i/copy"/"Paste to
   i/copy"). The browser's own native Paste callout/edit-menu is out of
   CSS's reach entirely — that part is system UI.
   ========================================================================== */

.wc-action {
  /* Selection has to stay on (it's what lets the platform offer its native
     paste/edit menu at all — `-webkit-touch-callout` is deliberately left
     at its default for the same reason: on iOS it can suppress that exact
     menu, not just the long-press callout its name suggests). This only
     drops the default mobile tap-highlight flash, so nothing suggests a
     text field was touched instead of a button. */
  -webkit-user-select: text;
  user-select: text;
  -webkit-tap-highlight-color: transparent;
  /* A contenteditable can grow a scrollbar or wrap oddly if its content
     somehow exceeded one line; it never should (see main.js: every paste is
     read from event.clipboardData and never actually inserted, and the
     label is always one short phrase), but this keeps a stray value from
     ever changing the button's height. */
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Small, non-toast line under the button pair (design point 2's "say so on
   the button... a small secondary line") for the one thing CSS/JS can't
   detect: whether a single tap reliably offers the native Paste menu on
   this device, or whether it needs a deliberate long-press. Shared by both
   controls — shown whenever either one is currently inviting a paste —
   updateActionUI toggles [hidden]. */
.wc-action__hint {
  margin: 0;
  padding: 0 var(--space-2);
  color: var(--text-muted);
  font-size: var(--fs-xs);
  text-align: center;
}

/* ==========================================================================
   Added in W7: opt-in clipboard preview (docs/tasks/w7-clipboard-preview.md)

   Off by default: `.wc-clippreview` stays `[hidden]` and the classic
   `.wc-clipboard-slot` above (unchanged since before this task) is all that
   shows — no residual controls, no layout shift, per the task's design
   section. When on, piece-card.js's `fillClipboardPreview` shows exactly
   one of three sibling blocks inside `.wc-clippreview` (placeholder /
   empty message / body+meta) plus the shared control at the bottom, which
   is a `contenteditable` paste target exactly like `.wc-action` (W5) for
   the same reason: a device that can't read the clipboard can still only
   get it from a native paste landing directly on this control.

   The truncated text's soft fade (mask-image, `data-truncated="true"`) is
   a purely static effect, not an animation — nothing here needs the
   `prefers-reduced-motion` guard tokens.css already zeroes `--dur*` under.
   The expanded text's own scroll region (`data-expanded="true"`, a capped
   `max-height`) is what keeps a 50,000-character clipboard from ever
   pushing the w/copy/i/copy buttons out of one-handed reach.
   ========================================================================== */

.wc-clippreview {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  /* Horizontal inset already comes from `.wc-piece`'s own `--card-pad`
     (the card's padding on every side) — this only adds vertical spacing
     under the bar, the same convention `.wc-piece__text` and
     `.wc-clipboard-slot` above already follow. */
  margin-top: var(--space-2);
}

.wc-clippreview[hidden] {
  display: none;
}

.wc-clippreview__placeholder {
  display: flex;
  justify-content: center;
  padding: var(--space-4) 0;
  color: var(--kind-clipboard);
}

.wc-clippreview__placeholder[hidden] {
  display: none;
}

.wc-clippreview__placeholder .wc-icon {
  width: 28px;
  height: 28px;
}

.wc-clippreview__empty {
  margin: 0;
  padding: var(--space-4) 0;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-align: center;
}

.wc-clippreview__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.wc-clippreview__body[hidden] {
  display: none;
}

/* The preview text itself: a <pre> so line breaks and leading/trailing
   whitespace render exactly as copied (design: "show leading and trailing
   whitespace faithfully rather than collapsing it"), wrapped rather than
   scrolled horizontally so a long unbroken line never widens the card. */
.wc-clippreview__text {
  margin: 0;
  overflow: hidden;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--text);
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
}

/* Collapsed and actually cut off: a soft fade hints there's more below,
   instead of an abrupt hard edge, without adding a scrollbar of its own. */
.wc-clippreview__text[data-truncated="true"] {
  -webkit-mask-image: linear-gradient(to bottom, #000 65%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 65%, transparent 100%);
}

/* Expanded: a bounded, scrollable region — never an infinite card. */
.wc-clippreview__text[data-expanded="true"] {
  max-height: 260px;
  overflow-y: auto;
}

.wc-clippreview__more {
  align-self: flex-start;
  border: none;
  background: transparent;
  padding: var(--space-1) 0;
  color: var(--accent);
  font-size: var(--fs-xs);
  font-weight: 700;
  cursor: pointer;
}

.wc-clippreview__more:hover {
  text-decoration: underline;
}

/* The quiet character-count + freshness line (design: "4,812 characters ·
   checked just now", ageing to "2 minutes ago" — the honesty requirement
   that this is a snapshot, not a live view, per D8). */
.wc-clippreview__meta {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
}

/* The shared "Show clipboard"/"Refresh" control — same contenteditable
   paste-target shape as .wc-action (W5, see that section's comment above
   for why user-select/tap-highlight/overflow are set this way), styled as
   a quiet outline button rather than .wc-action's solid fill, since this
   one is a secondary, repeatable check rather than the card's main action. */
.wc-clippreview__control {
  align-self: center;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  -webkit-user-select: text;
  user-select: text;
  -webkit-tap-highlight-color: transparent;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  max-width: 100%;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease);
}

.wc-clippreview__control:hover {
  background: var(--surface-2);
}

.wc-clippreview__control:active {
  transform: scale(0.98);
}

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

/* The eye toggle in the clipboard card's bar: accent-tinted while the
   preview is on, otherwise a plain muted icon button like every other
   .wc-iconbtn — no layout change either way, only color. */
.wc-piece--clipboard [data-action="toggle-clipboard-preview"][aria-pressed="true"] {
  color: var(--accent);
}

