/* ------------------------------------------------------------------ tokens */

:root,
[data-theme="dark"] {
  color-scheme: dark;
  --bg:            #0a0a0c;
  --surface:       #15151a;
  --surface-2:     #1d1d23;
  --line:          #26262d;
  --line-strong:   #33333c;
  --text:          #f2f2f3;
  --muted:         #a2a2ad;
  --faint:         #8b8b96;
  --accent:        #34d399;
  --accent-ink:    #04140d;
  --accent-soft:   rgba(52, 211, 153, 0.13);
  --danger:        #f87171;
  --danger-soft:   rgba(248, 113, 113, 0.12);
  /* On near-black a drop shadow is invisible, so depth comes from a lit top
     edge and a value step. These two carry it. */
  --edge:          rgba(255, 255, 255, 0.055);
  --inset:         inset 0 1px 2px rgba(0, 0, 0, 0.32);
  --shadow-sm:     0 1px 1px rgba(0, 0, 0, 0.32), 0 2px 6px -2px rgba(0, 0, 0, 0.4);
  --shadow:        0 1px 1px rgba(0, 0, 0, 0.3), 0 18px 44px -26px rgba(0, 0, 0, 0.95);
  --lift:          radial-gradient(120% 70% at 50% -20%, rgba(255, 255, 255, 0.045), transparent 70%);
}

[data-theme="light"] {
  color-scheme: light;
  --bg:            #f7f7f8;
  --surface:       #ffffff;
  --surface-2:     #f4f4f5;
  --line:          #e6e6e9;
  --line-strong:   #d6d6db;
  --text:          #16161a;
  --muted:         #63636e;
  --faint:         #6b6b75;
  --accent:        #047857;
  --accent-ink:    #ffffff;
  --accent-soft:   rgba(4, 120, 87, 0.10);
  --danger:        #c02626;
  --danger-soft:   rgba(192, 38, 38, 0.09);
  --edge:          rgba(255, 255, 255, 0.9);
  --inset:         inset 0 1px 2px rgba(24, 24, 27, 0.05);
  --shadow-sm:     0 1px 2px rgba(24, 24, 27, 0.06), 0 2px 6px -2px rgba(24, 24, 27, 0.08);
  --shadow:        0 1px 2px rgba(24, 24, 27, 0.06), 0 18px 40px -26px rgba(24, 24, 27, 0.32);
  --lift:          radial-gradient(120% 70% at 50% -20%, rgba(24, 24, 27, 0.035), transparent 70%);
}

:root {
  --r:      8px;
  --r-sm:   6px;
  /* One easing for the whole surface, so motion reads as one idea. */
  --ease:   cubic-bezier(0.16, 1, 0.3, 1);
  --fast:   140ms;
  --base:   220ms;
  --sans:   ui-sans-serif, -apple-system, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono:   ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
}

/* ------------------------------------------------------------- foundation */

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

html { -webkit-text-size-adjust: 100%; scrollbar-color: var(--line-strong) transparent; }

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--lift), var(--bg);
  background-attachment: fixed;
  color: var(--text);
  font: 400 15px/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--accent); color: var(--accent-ink); }

:where(input, select, button, textarea, a) { caret-color: var(--accent); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border: 4px solid var(--bg);
  border-radius: 999px;
}
::-webkit-scrollbar-thumb:hover { background: var(--faint); }

a { color: inherit; text-underline-offset: 3px; }

.i {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ----------------------------------------------------------------- topbar */

.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px clamp(16px, 4vw, 32px);
  background: color-mix(in srgb, var(--bg) 82%, var(--surface));
  border-bottom: 1px solid var(--line);
  box-shadow: inset 0 1px 0 var(--edge), 0 8px 24px -20px rgba(0, 0, 0, 0.9);
}

.brand {
  display: flex;
  align-items: center;
  color: inherit;
  text-decoration: none;
}

/* The mark carries its own tight crop, so no optical padding is added. */
.logo { display: block; height: 18px; width: auto; color: var(--text); }

.topbar-actions { display: flex; align-items: center; gap: 8px; }
.topbar-actions form { display: contents; }

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 38px;
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background var(--fast) var(--ease), color 160ms ease, border-color 160ms ease, transform var(--fast) var(--ease);
}

.btn:active:not([disabled]) { transform: translateY(1px); }
.btn[disabled] { opacity: 0.55; cursor: not-allowed; }

.btn.primary {
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}

.btn.primary:hover:not([disabled]) {
  background: color-mix(in srgb, var(--accent) 88%, var(--text));
}

.btn.ghost { border-color: var(--line); color: var(--muted); }

.btn.ghost:hover {
  color: var(--text);
  border-color: var(--line-strong);
  background: var(--line);
}

.btn.small { height: 32px; padding: 0 11px; font-size: 13px; border-color: var(--line); }
.btn.small:hover { background: var(--surface-2); border-color: var(--line-strong); }
.btn.block { width: 100%; height: 42px; }

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: color var(--fast) var(--ease), border-color 160ms ease, background 160ms ease;
}

.icon-btn:hover {
  color: var(--text);
  border-color: var(--line-strong);
  background: var(--line);
}

.icon-btn .moon { display: none; }
[data-theme="light"] .icon-btn .sun { display: none; }
[data-theme="light"] .icon-btn .moon { display: block; }

/* ----------------------------------------------------------------- layout */

main {
  max-width: 1120px;
  margin: 0 auto;
  padding: clamp(24px, 5vw, 44px) clamp(16px, 4vw, 32px) 72px;
}

h1, h2 { margin: 0; letter-spacing: -0.02em; }

.composer {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: clamp(18px, 3vw, 26px);
  box-shadow: inset 0 1px 0 var(--edge), var(--shadow);
}

.composer h1 { font-size: 21px; font-weight: 600; margin-bottom: 16px; }

.composer-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 190px auto;
  gap: 12px;
  align-items: end;
}

/* ----------------------------------------------------------------- fields */

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

.field label {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  letter-spacing: 0.01em;
}

input[type="text"],
input[type="password"],
input[type="search"],
input[type="date"],
select {
  width: 100%;
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  transition: border-color var(--fast) var(--ease), background 160ms ease;
}

input::placeholder { color: var(--faint); }
input:hover, select:hover { border-color: var(--line-strong); }

input:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

select {
  appearance: none;
  padding-right: 32px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2374747f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 15px;
  cursor: pointer;
}

/* ------------------------------------------------------------------ notes */

.form-note {
  margin: 10px 0 0;
  min-height: 20px;
  font-size: 13px;
  color: var(--muted);
}

.form-note.bad { color: var(--danger); }

.result {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--accent-soft);
  animation: rise 220ms cubic-bezier(0.16, 1, 0.3, 1);
}

.result .i { color: var(--accent); }

.result-link {
  flex: 1;
  min-width: 0;
  font-family: var(--mono);
  font-size: 14px;
  color: var(--text);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.result-link:hover { text-decoration: underline; }

/* ------------------------------------------------------------------- list */

.list { margin-top: clamp(28px, 5vw, 40px); }

.list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.list-head h2 { font-size: 18px; font-weight: 600; }

.tally {
  margin-left: 6px;
  font-weight: 400;
  font-size: 13px;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

.list-tools { display: flex; align-items: center; gap: 8px; }

.search { position: relative; }

.search .i {
  position: absolute;
  left: 11px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--faint);
  pointer-events: none;
}

.search input { width: 210px; padding-left: 34px; }

/* ---------------------------------------------------------------- filters */

/* State is the fastest way to cut a list down, so it gets the row above the
   table rather than hiding in a menu. */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 2px 0 18px;
}

.filter {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  transition: color var(--fast) var(--ease), background 160ms ease, border-color 160ms ease;
}

.filter:hover { color: var(--text); border-color: var(--line-strong); background: var(--line); }

.filter.is-on {
  background: var(--text);
  border-color: var(--text);
  color: var(--bg);
  font-weight: 600;
  box-shadow: var(--shadow-sm);
}

.count {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}

/* ------------------------------------------------------------------ table */

.table { --grid: 84px minmax(0, 1fr) 220px 72px 160px; }


/* ------------------------------------------------------------ slug prefix */

/* The domain is fixed, so it lives in the field rather than in the data. */
.slug-group {
  display: flex;
  align-items: center;
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  transition: border-color var(--fast) var(--ease), background 160ms ease;
}

.slug-group:hover { border-color: var(--line-strong); }
.slug-group:focus-within {
  border-color: var(--accent);
  background: var(--surface);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.slug-prefix {
  flex: none;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--faint);
  user-select: none;
}

.slug-group input {
  flex: 1;
  min-width: 0;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  font-family: var(--mono);
  font-size: 13px;
}

.slug-group input:hover,
.slug-group input:focus {
  border: 0;
  background: none;
  box-shadow: none;
}

/* -------------------------------------------------------------------- rows */

.rows {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.row {
  display: grid;
  grid-template-columns: var(--grid, 84px minmax(0, 1fr) 220px 72px 160px);
  align-items: center;
  gap: 16px;
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  /* The lit top edge is what makes a dark card read as a surface. */
  box-shadow: inset 0 1px 0 var(--edge), var(--shadow-sm);
  cursor: pointer;
  transition:
    border-color var(--base) var(--ease),
    background var(--base) var(--ease),
    box-shadow var(--base) var(--ease),
    opacity var(--base) var(--ease),
    filter var(--base) var(--ease);
}

/* A hint of lift, no more: the border moves one step and the surface warms
   slightly. Enough to follow the pointer, quiet enough to ignore. */
.row:hover {
  border-color: var(--line-strong);
  background: var(--surface-2);
  box-shadow: inset 0 1px 0 var(--edge), var(--shadow);
}

/* The row being edited holds the floor; everything else steps back and blurs
   so it is obvious which one is live. */
.rows.has-open-panel .row:not(.is-open) {
  opacity: 0.35;
  filter: blur(1.5px);
}

.row.is-open {
  border-color: color-mix(in srgb, var(--accent) 70%, var(--line));
  background: var(--surface);
  box-shadow: inset 0 1px 0 var(--edge), var(--shadow);
}

.row.fresh { animation: flash 1100ms var(--ease); }
.row.is-offline .row-thumb { opacity: 0.4; filter: saturate(0.2); }

@keyframes flash {
  from { background: var(--accent-soft); border-color: var(--accent); }
  to   { background: var(--surface); border-color: var(--line); }
}

@keyframes rise {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* The share card is the richest asset this tool owns, so it leads the row. */
.row-thumb {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1200 / 630;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  box-shadow: var(--shadow-sm);
}

.row-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--base) var(--ease);
}

.row:hover .row-thumb img { transform: scale(1.02); }

.row-thumb.is-blank {
  border-style: dashed;
  border-color: var(--line-strong);
}

.row-thumb.is-blank .i { width: 15px; height: 15px; color: var(--faint); }

/* ------------------------------------------------------------- row cells */

.cell-dest {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  font-size: 13px;
  color: var(--muted);
}

/* Until a site answers with one, the icon takes no space at all. */
.favi {
  flex: none;
  width: 16px;
  height: 16px;
  border-radius: 4px;
  object-fit: contain;
}

.dest-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cell-num {
  text-align: right;
  font-size: 13px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.clicks { font-weight: 600; color: var(--text); }

/* Actions that belong to the short link itself: small, quiet, adjacent. */
.link-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 24px;
  height: 24px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--faint);
  cursor: pointer;
  transition: color var(--fast) var(--ease), background 160ms ease;
}

.link-btn .i { width: 14px; height: 14px; }
.link-btn:hover { color: var(--text); background: var(--line); }
.copy-btn.done { color: var(--accent); }
.copy-btn .check { display: none; }
.copy-btn.done .check { display: block; }
.copy-btn.done .dup { display: none; }

.row-main { min-width: 0; display: flex; flex-direction: column; gap: 3px; }

.row-name {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.row-name:hover { text-decoration: underline; }

.row-url-line { display: flex; align-items: center; gap: 1px; min-width: 0; }

.row-url {
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.row-url .kw { color: var(--accent); }
.row-url .pre { color: var(--faint); }

.row-note {
  margin: 1px 0 0;
  font-size: 13px;
  line-height: 1.4;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.row-sub {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 12px;
  min-width: 0;
  font-size: 12.5px;
  color: var(--muted);
}

.row-trail {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.row-meta { display: flex; align-items: center; gap: 2px; justify-self: end; }

.row-actions { display: flex; align-items: center; gap: 2px; }

/* Actions sit quietly at rest and come up to full contrast on the row, so the
   row reads complete without five loud buttons fighting the card. */
.row-meta .act-btn { color: var(--faint); }
.row:hover .row-meta .act-btn { color: var(--muted); }
.row-meta .act-btn:hover { color: var(--text); }

.act-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--faint);
  cursor: pointer;
  transition: color var(--fast) var(--ease), background 160ms ease, border-color 160ms ease;
}

/* Reads as a real target under the pointer, not a change you have to hunt for. */
.act-btn:hover {
  color: var(--text);
  background: var(--line);
  border-color: var(--line-strong);
}

.act-btn.del-btn:hover {
  color: var(--danger);
  background: var(--danger-soft);
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
}

.act-btn.power-btn.is-off { color: var(--danger); }
.act-btn.power-btn.is-off:hover {
  color: var(--danger);
  background: var(--danger-soft);
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
}

.act-btn.lock-btn.is-on { color: var(--accent); }
.act-btn.lock-btn.is-on:hover {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}

.act-btn.card-btn.is-on { color: var(--accent); }
.act-btn.card-btn.is-on:hover {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}

.row.is-offline .row-main { opacity: 0.55; }

.flags { display: flex; align-items: center; gap: 10px; }
.flags:empty { display: none; }

/* Statuses, not controls: plain text with a tinted mark, so they read as
   facts about the link instead of buttons sitting next to it. */
.flag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--muted);
}

.flag .i { width: 12px; height: 12px; }

.flag.is-lock, .flag.is-lock .i { color: var(--accent); }
.flag.is-off, .flag.is-off .i { color: var(--danger); }
.flag.is-warn, .flag.is-warn .i { color: var(--danger); }

/* Inline row panel: edit, password, delete */

.panel {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 10px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  animation: rise var(--base) var(--ease);
}

.panel-fields { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.panel-fields .field { flex: 1 1 240px; }

/* The link form: where it goes on its own line, then the two short settings
   together, then the note with whatever room is left. */
.panel-fields.fields-edit {
  display: grid;
  grid-template-columns: 190px 168px minmax(0, 1fr);
  gap: 12px;
  align-items: end;
}

.fields-edit .field { flex: none; }
.fields-edit .field-url { grid-column: 1 / -1; }
.fields-edit .field-slug { grid-column: 1; }
.fields-edit .field-date { grid-column: 2; }
.fields-edit .field-note { grid-column: 3; }

/* The date picker's own control needs the same hit area as the text fields. */
input[type="date"] { font-family: var(--mono); font-size: 13px; }
input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: 0.55;
  cursor: pointer;
  filter: invert(1);
}

[data-theme="light"] input[type="date"]::-webkit-calendar-picker-indicator { filter: none; }

.panel-text { margin: 0; font-size: 13px; color: var(--muted); }
/* Save sits where a save belongs; anything that is not the save uses .mr-auto
   to take the other end. */
.panel-actions { display: flex; justify-content: flex-end; gap: 8px; }
.panel-actions .mr-auto { margin-right: auto; }

/* Share-card editor */

.qr-grid { display: flex; flex: 1 1 100%; gap: 20px; align-items: flex-start; }

.qr-box {
  flex: none;
  width: 168px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  /* Codes need light behind them to scan, whatever theme the manager is in. */
  background: #fff;
}

.qr-box svg { display: block; width: 100%; height: auto; }

.qr-side {
  flex: 1 1 240px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

.qr-url {
  margin: 0;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text);
  word-break: break-all;
}

.og-grid { display: flex; flex: 1 1 100%; gap: 14px; align-items: flex-start; }

.og-thumb {
  flex: none;
  width: 200px;
  aspect-ratio: 1200 / 630;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  font-size: 11px;
  color: var(--faint);
}

.og-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }

.og-fields {
  flex: 1 1 240px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.og-fields .field { flex: none; }

.panel-note { margin: 0; font-size: 12px; color: var(--muted); }
.panel-note:empty { display: none; }
.panel-note.bad { color: var(--danger); }

.danger-btn {
  background: var(--danger);
  color: #fff;
  border-color: transparent;
  font-weight: 600;
}

.danger-btn:hover:not([disabled]) { background: color-mix(in srgb, var(--danger) 86%, #000); }

/* ------------------------------------------------------------- empty state */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 68px 24px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r);
  text-align: center;
  color: var(--muted);
}

.empty-mark {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: 6px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
}

.empty-mark .logo { height: 15px; color: var(--muted); }

.empty-lead { margin: 0; font-size: 15px; font-weight: 600; color: var(--text); }
.empty-hint { margin: 0; font-size: 13px; max-width: 42ch; }

/* A miss in search carries no onboarding, so it drops the mark and the lead. */
.empty.is-search { padding: 40px 24px; }
.empty.is-search .empty-mark { display: none; }
.empty.is-search .empty-lead { font-weight: 400; color: var(--muted); }

/* `display: flex` above would otherwise beat the UA rule for [hidden]. */
.result[hidden],
.empty[hidden] { display: none; }

/* -------------------------------------------------------------------- auth */

.auth-body { display: grid; place-items: center; padding: 24px; }
.auth { width: 100%; max-width: 372px; }

.auth-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 28px;
  box-shadow: var(--shadow);
}

.auth-card .brand { margin-bottom: 22px; }
.auth-card h1 { font-size: 20px; font-weight: 600; }
.auth-sub { margin: 4px 0 22px; font-size: 14px; color: var(--muted); }
.auth-card form { display: flex; flex-direction: column; gap: 14px; }
.auth-card form .btn { margin-top: 4px; }

.alert {
  margin: 0 0 16px;
  padding: 9px 12px;
  border: 1px solid color-mix(in srgb, var(--danger) 35%, transparent);
  border-radius: var(--r-sm);
  background: var(--danger-soft);
  color: var(--danger);
  font-size: 13px;
}

/* -------------------------------------------------------------- responsive */

/* Columns drop one at a time as the width runs out, so the table keeps its
   shape instead of everything squashing at once. Destination is the only
   optional column left, and it is the one to lose: the short link above it
   already says where a link points. */
@media (max-width: 980px) {
  .table { --grid: 84px minmax(0, 1fr) 72px 160px; }
  .row > :nth-child(3) { display: none; }
}

@media (max-width: 720px) {
  .composer-row { grid-template-columns: minmax(0, 1fr) auto; }
  .slug-field { grid-column: 1 / -1; order: 3; }
  .composer-row .btn.primary { grid-column: 2; grid-row: 1; }

  .list-head { align-items: stretch; }
  .list-tools { width: 100%; }
  .search { flex: 1; }
  .search input { width: 100%; }
}

/* Narrow: the row stops being a table and becomes a card with its actions on
   their own line, so every target stays tappable. */
@media (max-width: 640px) {
  .row {
    grid-template-columns: 76px minmax(0, 1fr);
    gap: 12px 14px;
  }

  /* Destination is worth the line; the count is not, on a phone. */
  .row > :nth-child(3) {
    display: flex;
    grid-column: 1 / -1;
    padding-top: 2px;
  }

  .row > :nth-child(4) { display: none; }

  .og-grid { flex-direction: column; }
  .og-thumb { width: 100%; aspect-ratio: 1200 / 630; }

  .row-meta {
    grid-column: 1 / -1;
    justify-self: stretch;
    justify-content: flex-end;
    gap: 4px;
    margin-top: 6px;
    padding-top: 10px;
    border-top: 1px solid var(--line);
  }

  .act-btn { width: 36px; height: 36px; }
  .link-btn { width: 30px; height: 30px; }
  .panel-fields .field { flex: 1 1 100%; }

  .panel-fields.fields-edit { grid-template-columns: 190px minmax(0, 1fr); }
  .fields-edit .field-slug { grid-column: 1; }
  .fields-edit .field-date { grid-column: 2; }
  .fields-edit .field-note { grid-column: 1 / -1; }
}

@media (max-width: 430px) {
  .composer-row { grid-template-columns: minmax(0, 1fr); }
  .composer-row .btn.primary { grid-column: 1; grid-row: auto; width: 100%; }
  .slug-field { order: 0; }
  .row { grid-template-columns: 64px minmax(0, 1fr); }
  .qr-grid { flex-direction: column; }
  .qr-box { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------- micro-motion */

/* Small controls answer the pointer with a press, not just a tint. */
.act-btn:active,
.link-btn:active,
.icon-btn:active,
.copy-btn:active { transform: scale(0.92); }

.link-btn,
.act-btn,
.copy-btn,
.icon-btn {
  transition:
    color var(--fast) var(--ease),
    background var(--fast) var(--ease),
    border-color var(--fast) var(--ease),
    transform var(--fast) var(--ease);
}

.filter {
  transition:
    color var(--fast) var(--ease),
    background var(--fast) var(--ease),
    border-color var(--fast) var(--ease),
    transform var(--fast) var(--ease);
}

.filter:active { transform: scale(0.97); }

/* The count ticks when a filter changes, so a shift in the list is noticed. */
.count { transition: color var(--fast) var(--ease); }
.filter.is-on .count { color: var(--bg); }

/* Destination icons arrive a beat after the row paints. */
.favi {
  opacity: 0;
  transform: scale(0.85);
  transition: opacity var(--base) var(--ease), transform var(--base) var(--ease);
}

.favi.is-in { opacity: 1; transform: none; }

/* The share card belongs to the row: it eases in, it does not snap. */
.row-thumb { transition: opacity var(--base) var(--ease), filter var(--base) var(--ease); }
