/* ============================================================
   Timeline editor — full-width application shell
   ============================================================ */

html, body.app { height: 100%; overflow: hidden; }
/* clip, where supported, is not a scroll container. On a screen narrower than the top
   bar, a hidden body could still be scrolled sideways by focusing a field. */
body.app { overflow: clip; }

.app-shell {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
}

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

.app-bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 1rem;
  height: 56px;
  padding: 0 1rem;
  border-bottom: 1px solid var(--line);
  background: var(--white);
  z-index: 40;
}
.app-bar .brand-name { font-size: 1.05rem; }
.app-bar .spacer { flex: 1; }

.title-input {
  font-family: var(--serif);
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--ink);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: .3em .55em;
  width: min(34ch, 40vw);
  background: transparent;
}
.title-input:hover:not(:disabled) { border-color: var(--line); }
.title-input:disabled { color: var(--ink); opacity: 1; }

.save-state {
  font-size: .8rem;
  color: var(--faint);
  min-width: 8ch;
  white-space: nowrap;
  transition: color .2s ease;
}
.save-state[data-state="unsaved"] { color: var(--gold); }
.save-state[data-state="error"] { color: var(--danger); }

.divider-v { width: 1px; height: 24px; background: var(--line); flex: none; }

/* ---------- tool bar ---------- */

.tool-bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
  height: 48px;
  padding: 0 1rem;
  border-bottom: 1px solid var(--line);
  background: var(--white);
  font-size: .86rem;
  z-index: 30;
}
.tool-bar .spacer { flex: 1; }
.tool-group { display: flex; align-items: center; gap: .4rem; }
.tool-group > .lbl { color: var(--muted); font-size: .8rem; white-space: nowrap; }
/* The date under the pointer, set like the toolbar's labels, in figures of
   one width so it holds still as it changes. */
.hover-time { color: var(--muted); font-size: .8rem; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tool-bar select { width: auto; font-size: .84rem; padding: .35em 1.9em .35em .6em; }

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 30px; height: 30px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink-2);
  cursor: pointer;
  padding: 0;
  transition: background .14s ease, border-color .14s ease, color .14s ease;
}
.icon-btn:hover:not(:disabled) { background: var(--line-soft); color: var(--ink); }
.icon-btn:disabled { opacity: .4; cursor: not-allowed; }
.icon-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }

.zoom-slider { width: 150px; accent-color: var(--accent); cursor: pointer; }

.readonly-flag {
  font-size: .78rem;
  font-weight: 600;
  color: var(--gold);
  background: var(--gold-soft);
  padding: .25em .6em;
  border-radius: 999px;
}

/* ---------- guest banner ---------- */

.guest-bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .5rem 1rem;
  border-bottom: 1px solid #ecdfc2;
  background: var(--gold-soft);
  color: #6f5417;
  font-size: .86rem;
  z-index: 29;
}
.guest-bar .spacer { flex: 1; }
.guest-bar svg { flex: none; color: var(--gold); }
.guest-bar .btn-quiet { color: #6f5417; }
.guest-bar .btn-quiet:hover { background: rgba(176, 129, 42, .12); color: #4d3a10; }

/* Sharpens once the visitor has work that would be a shame to lose. */
.guest-bar.urgent {
  background: #f7ecd4;
  border-bottom-color: #e3cf9f;
  font-weight: 500;
}

/* ---------- main area ---------- */

.app-main { flex: 1; display: flex; min-height: 0; position: relative; }

.stage {
  flex: 1;
  position: relative;
  min-width: 0;
  overflow: hidden;
  background: var(--white);
  touch-action: none;
}

.ruler {
  position: absolute;
  inset: 0 0 auto 0;
  height: 54px;
  z-index: 20;
  background: var(--white);
  border-bottom: 1px solid var(--line);
  display: block;
  cursor: ew-resize;
}

.grid-canvas {
  position: absolute;
  inset: 54px 0 0 0;
  z-index: 1;
  display: block;
}

.events-layer {
  position: absolute;
  inset: 54px 0 0 0;
  z-index: 2;
  overflow: hidden;
}

.stage.panning { cursor: grabbing; }
.stage.can-pan { cursor: grab; }

/* ---------- event chips ---------- */

.ev {
  position: absolute;
  height: 28px;
  pointer-events: none;
  /* A drag that an anchor refuses leaves the pointer sweeping across
     the label, which would otherwise select its text. */
  user-select: none;
  -webkit-user-select: none;
  --ev: var(--accent);
  --ev-soft: var(--accent-soft);
  --ev-text: var(--ink);
  --grp: var(--accent);
}

/* Only the painted parts take pointer events, so a zero-width point
   event never blocks a background drag. */
.ev-bar, .ev-point, .ev-tail, .ev-handle { pointer-events: auto; }

.ev-bar, .ev-point, .ev-tail { cursor: grab; }
.ev.dragging .ev-bar, .ev.dragging .ev-point, .ev.dragging .ev-tail { cursor: grabbing; }
.ev.anchored .ev-bar, .ev.anchored .ev-point, .ev.anchored .ev-tail { cursor: default; }
.ev.readonly .ev-bar, .ev.readonly .ev-point, .ev.readonly .ev-tail { cursor: pointer; }

/* span bar. It clips, so the uncertain stretches inside it keep to its
   rounded corners. */
.ev-bar {
  position: absolute;
  left: 0; right: 0; top: 4px; bottom: 4px;
  background: var(--ev-soft);
  border: 1px solid var(--ev);
  border-radius: 5px;
  min-width: 3px;
  overflow: hidden;
}
.ev.selected .ev-bar { box-shadow: 0 0 0 2px var(--white), 0 0 0 4px var(--ev); }

/* Point marker. The element is deliberately larger than the dot it
   draws, so a single moment is still easy to grab with a mouse. */
.ev-point {
  position: absolute;
  left: 0; top: 50%;
  width: 22px; height: 22px;
  margin: -11px 0 0 -11px;
  border-radius: 50%;
}
.ev-point::after {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 11px; height: 11px;
  margin: -5.5px 0 0 -5.5px;
  background: var(--ev);
  border-radius: 50%;
  border: 2px solid var(--white);
  box-shadow: 0 0 0 1px var(--ev);
}
.ev.selected .ev-point::after { box-shadow: 0 0 0 1px var(--ev), 0 0 0 4px var(--ev-soft); }

/* Uncertainty on a period. The best guess keeps its solid outline, and
   every uncertain stretch gets the same soft diagonal bands, whether the
   event could be longer (beyond the bar) or shorter (inside it). The bands
   are the bar's own fill a shade deeper, so they show on white.

   Each square tile holds two bands corner to corner, which is what lets
   tiles meet without a seam. The renderer sets background-position so every
   stretch shares one tile grid, and the bands run on unbroken from inside a
   bar to beyond it.

   A stretch beyond the bar tucks under its end and sits behind every bar
   (z-index -1 inside the events layer), so a neighbor's best guess always
   shows in front of it. A stretch inside the bar is clipped by the bar's
   corners and rounds its own. */
.ev-unc, .ev-unc-in {
  --band: color-mix(in srgb, var(--ev-soft), var(--ev) 15%);
  position: absolute;
  pointer-events: none;
  background-color: var(--white);
  background-image: linear-gradient(135deg,
    var(--band) 0 29.2%, transparent 29.2% 50%, var(--band) 50% 79.2%, transparent 79.2% 100%);
  background-size: 13px 13px;
}
.ev-unc { top: 4px; bottom: 4px; z-index: -1; }
.ev-unc.before { border-radius: 5px 0 0 5px; }
.ev-unc.after { border-radius: 0 5px 5px 0; }
.ev-unc-in { top: 0; bottom: 0; }
.ev-unc-in.start { left: 0; border-radius: 0 4px 4px 0; }
.ev-unc-in.end { right: 0; border-radius: 4px 0 0 4px; }

/* A moment's uncertainty is a whisker: a fine line either side of its dot,
   with a tick where it runs out. */
.ev-point-kind .ev-unc {
  top: 50%; bottom: auto;
  height: 0;
  background: none;
  border-top: 1px solid var(--ev);
  border-radius: 0;
  opacity: .6;
}
.ev-point-kind .ev-unc::after {
  content: "";
  position: absolute;
  top: -4px;
  width: 1px; height: 9px;
  background: var(--ev);
}
.ev-point-kind .ev-unc.before::after { left: 0; }
.ev-point-kind .ev-unc.after::after { right: 0; }

/* label and badges travel together in a shrink-wrapped row */
.ev-tail {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 4px;
  width: max-content;
  max-width: 340px;
  height: 20px;
  z-index: 2;
}
/* The label clips for its ellipsis, so its line box has to be tall enough
   for descenders: at line-height 1 the tails of g, p and y were cut off.
   --ev-text is the event's color, darkened where needed to stay readable
   (see colors.js), and it is the same inside a bar and beside one. */
.ev-label {
  font-size: 12px;
  line-height: 16px;
  font-weight: 550;
  color: var(--ev-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ev-label.untitled { color: var(--faint); font-style: italic; font-weight: 400; }

/* A name with no room inside or beside its bar hangs under it, in the 22px
   between this row's bar and the next row's, from a tick at the bar's start
   (a moment's dot) that shows whose name it is even where it runs on under
   later bars. render.js places it: HANG_LEFT, HANG_MID. */
.ev-tail.hang { top: 25px; transform: none; }
.ev-tail.hang::before {
  content: "";
  position: absolute;
  left: -5px; top: -1px;
  width: 1px; height: 11px;
  background: var(--ev);
  opacity: .6;
}
.ev-point-kind .ev-tail.hang::before { left: -6.5px; top: -4px; height: 14px; }

/* A dark corner marks a period whose name has no room anywhere near its bar.
   Pointing at the bar shows the name. --flag is set to suit the bar's width. */
.ev-flag {
  position: absolute;
  left: 0; top: 4px;
  width: 0; height: 0;
  border-top: var(--flag, 7px) solid var(--ev);
  border-right: var(--flag, 7px) solid transparent;
  border-top-left-radius: 5px;
  pointer-events: none;
}

/* resize handles */
.ev-handle {
  position: absolute;
  top: 0; bottom: 0;
  width: 10px;
  cursor: ew-resize;
  z-index: 3;
}
.ev-handle.l { left: -5px; }
.ev-handle.r { right: -5px; }

/* Every badge is a solid box with a white icon. A note or anchor badge wears
   its event's label color, inside a bar or beyond it: colors.js keeps that
   color readable on white, so white is readable on it.

   16px, an even size, is what centers a badge exactly in the 18px inside a
   bar's border, a pixel clear of it at top and bottom. A 17px badge sat on
   half pixels and touched the border on one side. No shadow either, which
   made a badge look lower than it is. */
.ev-badge {
  width: 16px; height: 16px;
  border-radius: 4px;
  border: 1px solid var(--ev-text);
  background: var(--ev-text);
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
  padding: 0;
  flex: none;
  transition: box-shadow .12s ease;
}
.ev-badge svg { display: block; }
.ev-badge.anchor { cursor: default; }
/* The ring means the note is showing. */
.ev-badge.note.on { box-shadow: 0 0 0 2px var(--white), 0 0 0 3.5px var(--ev-text); }

/* A ring reaches 3.5px beyond its badge, so the first badge sits 2px further
   from the label than the tail's gap, and a ring never covers the text.
   render.js counts those 2px as BADGE_LEAD. Nothing moves when a ring
   appears: a badge that shifted or grew as it was pointed at or clicked
   jiggled its icon. */
.ev-label + .ev-badge { margin-left: 2px; }

/* Link badges wear their group's color instead, so which events move
   together can be read straight off the canvas. */
.ev-badge.link { background: var(--grp); border-color: var(--grp); }
.ev-badge.link:hover, .ev-badge.link:focus-visible, .ev-badge.link.open {
  box-shadow: 0 0 0 2px var(--white), 0 0 0 3.5px var(--grp);
  outline: none;
}

/* Every member of a group, while one of its badges is hovered or open. */
.ev.grp-lit .ev-bar { box-shadow: 0 0 0 2px var(--white), 0 0 0 3.5px var(--grp); }
.ev.grp-lit .ev-point::after { box-shadow: 0 0 0 1px var(--ev), 0 0 0 3px var(--white), 0 0 0 4.5px var(--grp); }
.ev.grp-lit .ev-badge.link { box-shadow: 0 0 0 2px var(--white), 0 0 0 3.5px var(--grp); }

/* The lines joining a hovered event to whatever it is linked to. */
.link-lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  z-index: 1;
}
/* An event's own links are dashed; the rest of its group is dotted. */
.link-lines .link-line { fill: none; stroke-linecap: round; }
.link-lines .link-line.direct { stroke-width: 1.6; stroke-dasharray: 5 4; opacity: .95; }
.link-lines .link-line.further { stroke-width: 2; stroke-dasharray: 0 4.5; opacity: .75; }
.link-lines .link-end { stroke: var(--white); stroke-width: 1.5; }

/* layered events from someone else's public timeline */
.ev.overlay { opacity: .82; }
.ev.overlay .ev-bar { border-style: dashed; background: transparent; }
.ev.overlay .ev-unc, .ev.overlay .ev-unc-in { background-color: transparent; }
.ev.overlay .ev-label { color: var(--muted); font-weight: 500; }
.ev.overlay .ev-bar, .ev.overlay .ev-point, .ev.overlay .ev-tail { cursor: default; }

/* ---------- note popovers ---------- */

.note-pop {
  position: absolute;
  z-index: 12;
  width: 250px;
  background: var(--white);
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  padding: .6rem .75rem;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 180px;
  overflow-y: auto;
}
.note-pop .np-title {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: .3rem;
}

/* ---------- link details ---------- */

.link-pop {
  position: absolute;
  z-index: 14;
  width: 290px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 3px solid var(--grp, var(--accent));
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  padding: .55rem .75rem .7rem;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink-2);
  cursor: default;
}
.lp-head { display: flex; align-items: center; gap: .45rem; }
.lp-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 19px; height: 19px;
  border-radius: 5px;
  background: var(--grp, var(--accent));
  color: #fff;
}
.lp-icon svg { display: block; }
.lp-title { flex: 1; min-width: 0; font-weight: 650; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lp-close, .cp-close {
  flex: none;
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  padding: 0;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}
.lp-close:hover, .cp-close:hover { background: var(--line-soft); color: var(--ink); }
.lp-status { margin: .35rem 0 .15rem; color: var(--muted); }
.lp-list { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: .3rem; }
.lp-row { display: flex; align-items: flex-start; gap: .5rem; }
.lp-text { flex: 1; min-width: 0; }
.lp-release { flex: none; margin-top: -.1rem; }
.lp-hint { margin: .65rem 0 0; font-size: 11.5px; color: var(--faint); }

/* A button that reads as a link: event names inside link descriptions. */
.link-btn {
  display: inline;
  font: inherit;
  font-weight: 600;
  color: var(--accent);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-align: left;
}
.link-btn:hover { text-decoration: underline; }
.link-btn:disabled { color: var(--ink-2); cursor: default; text-decoration: none; }

.btn-xs { font-size: .76rem; padding: .3em .5em; }

/* ---------- more colors ---------- */

.color-pop {
  position: fixed;
  z-index: 150;
  width: 314px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: .55rem .75rem .75rem;
}
.cp-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: .8rem;
  font-weight: 650;
  color: var(--ink);
  margin-bottom: .5rem;
}
.cp-caption { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--faint); margin-bottom: .3rem; }
.cp-recent { margin-bottom: .6rem; }
/* Fifteen columns of 16px cells fit the popup exactly. A row must never
   wrap, or the grid stops reading as hue across and tone down. */
.cp-grid { display: grid; gap: 3px; }
.cp-row { display: flex; flex-wrap: wrap; gap: 3px; }
.cp-grid .cp-row { flex-wrap: nowrap; }
.cp-row.cp-gap { margin-bottom: 7px; }
.cp-cell {
  flex: none;
  width: 16px; height: 16px;
  padding: 0;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
  transition: transform .1s ease, box-shadow .1s ease;
}
.cp-cell:hover, .cp-cell:focus-visible {
  transform: scale(1.25);
  box-shadow: 0 0 0 2px var(--white), 0 0 0 3px var(--ink);
  position: relative;
  z-index: 1;
  outline: none;
}
.cp-cell.on { box-shadow: 0 0 0 2px var(--white), 0 0 0 3.5px var(--ink); }
.cp-preview {
  display: flex;
  align-items: center;
  gap: .9rem;
  margin-top: .75rem;
  padding: .55rem .6rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
}
.cp-sample-bar {
  flex: 1.3;
  min-width: 0;
  height: 20px;
  border: 1px solid;
  border-radius: 5px;
  padding: 0 7px;
  display: flex;
  align-items: center;
  font-size: 12px;
  font-weight: 550;
  line-height: 16px;
}
.cp-sample-bar span, .cp-sample-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cp-sample-point { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 550; line-height: 16px; }
.cp-sample-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; box-shadow: 0 0 0 2px var(--white), 0 0 0 3px currentColor; }
.cp-foot { margin: .5rem 0 0; font-size: 11.5px; color: var(--faint); }

/* ---------- lane guides ---------- */

.lane-hint {
  position: absolute;
  left: 0; right: 0;
  height: 2px;
  background: var(--accent);
  opacity: .35;
  pointer-events: none;
  z-index: 11;
}

/* ---------- inspector ---------- */

/* The panel shuts by narrowing to nothing, and the canvas widens into the
   space as it goes (the stage's ResizeObserver redraws it). The content
   keeps its full width inside a clip, so it slides rather than reflowing,
   and the border slides with it. */
.inspector {
  --insp-w: 320px;
  --insp-ease: .26s cubic-bezier(.3, .7, .2, 1);
  flex: none;
  position: relative;
  width: var(--insp-w);
  z-index: 25;
  transition: width var(--insp-ease);
}
.inspector.closed { width: 0; }
.inspector.no-anim, .inspector.no-anim * { transition: none !important; }

/* clip, where supported, is not a scroll container, so focusing a field in
   a half-open panel cannot scroll the content out of line. */
.insp-clip { position: absolute; inset: 0; overflow: hidden; overflow: clip; }
.insp-scroll {
  width: var(--insp-w);
  height: 100%;
  overflow-y: auto;
  background: var(--white);
  border-left: 1px solid var(--line);
  padding: 1.1rem 1.15rem 3rem;
}

/* Hangs off the panel's edge, level with the ruler. While the panel is
   shut it moves wholly onto the canvas, and the chevron turns to point
   the way the panel will open. */
.insp-toggle {
  position: absolute;
  top: 13px;
  left: -14px;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 28px; height: 28px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--white);
  color: var(--ink-2);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: left var(--insp-ease), background .14s ease, border-color .14s ease, color .14s ease;
}
.insp-toggle:hover { background: var(--line-soft); border-color: var(--faint); color: var(--ink); }
.insp-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.insp-toggle svg { display: block; transition: transform var(--insp-ease); }
.inspector.closed .insp-toggle { left: -40px; }
.inspector.closed .insp-toggle svg { transform: rotate(180deg); }

.insp-head {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-height: 20px;
  margin-bottom: 1.1rem;
  /* clear of the toggle button hanging over the panel's edge */
  padding-left: .55rem;
}
.insp-head h2 {
  font-family: var(--sans);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 0;
}

.insp-section { margin-bottom: 1.25rem; }
.insp-section > .label { margin-bottom: .5em; }

.seg {
  display: flex;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.seg button {
  flex: 1;
  font: inherit;
  font-size: .84rem;
  padding: .48em .5em;
  border: 0;
  background: var(--white);
  color: var(--muted);
  cursor: pointer;
  transition: background .14s ease, color .14s ease;
}
.seg button + button { border-left: 1px solid var(--line); }
.seg button:hover { background: var(--line-soft); }
.seg button.on { background: var(--accent); color: #fff; }

/* Category, Precision and Certainty: each on one line, its control at the
   right, small enough that the three read as settings rather than as the
   event itself. */
.insp-settings { display: grid; gap: .5rem; margin-bottom: 1.25rem; }
.insp-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .35rem .75rem; min-height: 28px; }
/* Where the panel is too narrow for both, the control drops beneath its label, still at the right. */
.insp-row > :last-child { margin-left: auto; }
.insp-row > .label { margin: 0; }
.seg-sm { flex: none; }
.seg-sm button { flex: none; font-size: .76rem; line-height: 1.35; padding: .22em .65em; }

/* Start, End and Duration: the label at the left, level with the first row
   of fields, and the fields beside it. */
.field-row {
  display: grid;
  grid-template-columns: 4.1rem minmax(0, 1fr);
  column-gap: .5rem;
  align-items: start;
}
.field-row > .label { margin: 0; min-height: 2.15rem; display: flex; align-items: center; }
.insp-section.date-group, .insp-section.field-row { margin-bottom: .7rem; }

/* The dates are the heart of an event, so they sit together on a pale tint
   of the accent, reaching a little past the column so the fields inside
   stay in line with everything else. */
.insp-dates {
  margin: 0 -.6rem 1.25rem;
  padding: .7rem .6rem .05rem;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent-soft) 60%, var(--white));
}
.insp-dates .moment-note { margin: -.2rem 0 .7rem; }

/* A phone-width panel has no room for labels beside the fields: they go back above. */
@media (max-width: 363px) {
  .field-row { grid-template-columns: minmax(0, 1fr); }
  .field-row > .label { min-height: 0; margin-bottom: .45em; }
}

/* Date entry. Every row shares one grid, so month sits under year and day
   under era, and hour and minute below them, as precision reveals them. */
.date-row {
  display: grid;
  grid-template-columns: 4.6fr 3fr;
  gap: .35rem;
}
.date-row + .date-row, .date-row + .unc-row { margin-top: .35rem; }
.date-row input, .date-row select,
.duration-row input, .duration-row select { font-size: .85rem; padding: .42em .5em; }
.date-row select { padding-right: 1.6em; background-position: right .45em center; }

/* How much earlier and how much later a date could be, in one unit. */
.unc-row {
  display: grid;
  grid-template-columns: auto 1fr auto 1fr 1.45fr;
  align-items: center;
  gap: .3rem;
}
.unc-row input, .unc-row select { font-size: .8rem; padding: .45em .4em; }
.unc-row select { padding-right: 1.35em; background-position: right .35em center; }
.unc-sign { color: var(--gold); font-weight: 700; font-size: 1rem; text-align: center; min-width: .7em; }

.duration-row { display: grid; grid-template-columns: 1fr 1.25fr; gap: .35rem; }

.moment-note { margin: -.35rem 0 .9rem; }

/* Fifteen presets and "more colors" fill exactly two rows of eight. */
.swatches {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  justify-items: center;
  gap: .45rem 0;
}
.swatch {
  width: 26px; height: 26px;
  border-radius: 50%;
  border: 2px solid var(--white);
  box-shadow: 0 0 0 1px var(--line);
  cursor: pointer;
  padding: 0;
  transition: transform .12s ease, box-shadow .12s ease;
}
.swatch:hover { transform: scale(1.1); }
.swatch.on { box-shadow: 0 0 0 2px var(--ink); }
.swatch:disabled { cursor: default; transform: none; }

/* "More colors": hue runs across and tone runs down, a small version of
   the grid it opens. A custom color shows as a dot in the middle. */
.swatch.swatch-more {
  position: relative;
  border-radius: 7px;
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, .28), rgba(255, 255, 255, 0) 45%, rgba(0, 0, 0, .38)),
    linear-gradient(to right, #b73f6e, #bd413f, #ad5000, #936200, #597600, #007d37, #007b66, #006fc0, #5662ca, #8055be, #9e4aa4);
}
.swatch.swatch-more::after {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  background: var(--custom, transparent);
  box-shadow: 0 0 0 2px var(--white);
  opacity: 0;
}
.swatch.swatch-more.on::after { opacity: 1; }

.insp-note { min-height: 76px; font-size: .88rem; }

/* Anchor and Link: a switch each, labeled like the headings above, with
   its options dropping down beneath. */
.toggle-section { margin-bottom: 1rem; }
.toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  margin: 0;
  cursor: pointer;
}
.toggle-row > .label { margin: 0; cursor: inherit; }
.toggle-row:has(input:disabled) { cursor: default; }
.switch input:disabled { cursor: default; }
.switch input:disabled ~ .track { opacity: .55; }
.switch input:focus-visible ~ .track { box-shadow: 0 0 0 3px var(--accent-soft); }
.toggle-panel { margin-top: .6rem; }
.toggle-panel > .hint:first-child { margin-top: 0; }

/* links */
.link-hint { margin: .4rem 0 .3rem; }
.link-group { font-size: .84rem; color: var(--ink-2); margin: .45rem 0 .4rem; }
.link-list { display: grid; gap: .35rem; margin-bottom: .2rem; }
.link-row {
  font-size: .84rem;
  line-height: 1.45;
  color: var(--ink-2);
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  padding: .45em .6em;
}
.lr-actions { display: flex; justify-content: flex-end; gap: .15rem; margin: .15rem -.3rem -.2rem 0; }

/* A quiet text button, nothing like Delete event below it. */
.link-add {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  font: inherit;
  font-size: .8rem;
  font-weight: 600;
  color: var(--accent);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  padding: .15rem .3rem .15rem .1rem;
  cursor: pointer;
}
.link-add:hover:not(:disabled) { background: var(--accent-soft); }
.link-add:disabled { color: var(--faint); cursor: default; }
.link-add-plus { font-size: 1rem; line-height: 1; font-weight: 500; }

.link-editor {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: .65rem .7rem .7rem;
  margin-top: .2rem;
  display: grid;
  /* Without an explicit track the column grows to fit its widest select,
     and the form spills out of its card. */
  grid-template-columns: minmax(0, 1fr);
  gap: .4rem;
  font-size: .84rem;
  color: var(--ink-2);
}
.le-title { font-weight: 650; color: var(--ink); }
.le-line { display: flex; align-items: center; gap: .35rem; }
.le-line > span { white-space: nowrap; }
.le-line select, .le-line input { font-size: .84rem; padding: .38em .45em; }
.le-line select { width: auto; flex: 1; min-width: 0; padding-right: 1.6em; background-position: right .45em center; }
.le-line input[type="number"] { width: 4.6rem; flex: none; }
.le-hint { margin: 0; font-size: .78rem; }
.le-actions { display: flex; justify-content: flex-end; gap: .35rem; margin-top: .15rem; }

.insp-actions { display: flex; gap: .4rem; margin-top: 1.75rem; }
.insp-actions .btn { flex: 1; }

.insp-empty {
  margin: 3.2rem 0 0;
  color: var(--faint);
  font-size: .88rem;
  text-align: center;
}

/* ---------- credits footer strip ---------- */

.credit-strip {
  flex: none;
  border-top: 1px solid var(--line);
  background: var(--surface);
  padding: .45rem 1rem;
  font-size: .78rem;
  color: var(--muted);
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  align-items: center;
}
.credit-strip[hidden] { display: none; }
.credit-strip strong { font-weight: 600; color: var(--ink-2); }

/* ---------- modal ---------- */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(20, 23, 26, .32);
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 1.5rem;
}
.modal-backdrop[hidden] { display: none; }

.modal {
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  width: 100%;
  max-width: 560px;
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.15rem 1.35rem;
  border-bottom: 1px solid var(--line-soft);
}
.modal-head h2 { font-size: 1.15rem; margin: 0; }
.modal-body { padding: 1.35rem; overflow-y: auto; }
/* A question rather than a form: narrow, with the answer buttons close by. */
.modal.modal-sm { max-width: 400px; }
.modal-sm .modal-body { padding-bottom: .5rem; }
.confirm-text { margin: 0; color: var(--ink-2); font-size: .95rem; }

.modal-foot {
  display: flex; gap: .5rem; justify-content: flex-end;
  padding: 1rem 1.35rem;
  border-top: 1px solid var(--line-soft);
}

/* layer list inside modal */
.layer-list { display: grid; gap: .5rem; margin-top: 1rem; }
.layer-item {
  display: flex;
  align-items: center;
  gap: .75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: .7rem .85rem;
}
.layer-item .info { flex: 1; min-width: 0; }
.layer-item h4 { font-family: var(--sans); font-size: .93rem; font-weight: 620; margin: 0 0 .1rem; }
.layer-item p { font-size: .8rem; color: var(--faint); margin: 0; }
.layer-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }

.switch { position: relative; width: 36px; height: 20px; flex: none; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; z-index: 2; }
.switch .track {
  position: absolute; inset: 0;
  background: var(--line);
  border-radius: 999px;
  transition: background .16s ease;
}
.switch .track::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 16px; height: 16px;
  background: var(--white);
  border-radius: 50%;
  box-shadow: var(--shadow-sm);
  transition: transform .16s ease;
}
.switch input:checked ~ .track { background: var(--accent); }
.switch input:checked ~ .track::after { transform: translateX(16px); }

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

.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%) translateY(8px);
  background: var(--ink);
  color: #fff;
  font-size: .87rem;
  padding: .65em 1.1em;
  border-radius: 999px;
  box-shadow: var(--shadow-lg);
  z-index: 200;
  opacity: 0;
  pointer-events: none;
  transition: opacity .18s ease, transform .18s ease;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

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

@media (max-width: 900px) {
  /* Narrow screens lay the panel over the canvas instead of beside it. */
  .inspector {
    --insp-w: min(320px, 88vw);
    position: absolute;
    inset: 0 0 0 auto;
  }
  .insp-clip { box-shadow: var(--shadow-lg); transition: box-shadow var(--insp-ease); }
  .inspector.closed .insp-clip { box-shadow: none; }
  .title-input { width: 30vw; }
  .app-bar .brand-name { display: none; }
}
