/* The broadcast timetable's styles (static/tt/board.js), shared by the
   creative page and the admin page, plus the dialogs and toast of
   static/tt/common.js. The pages define the colour tokens (--line, --muted,
   --accent, --ok, --warn, --bad, --panel, --ring) themselves.

   Moved out of static/creative.html on 8 Oct 2026 unchanged. */

button.ghost { background: none; color: var(--muted); border: 1px solid var(--line); font-weight: 500; }
button.ghost:hover { background: none; }

/* ---------- scheduling board ---------- */
.board-bar { display: flex; gap: .8rem; align-items: center; flex-wrap: wrap; margin-bottom: 1rem; }
.bar-field { display: inline-flex; gap: .4rem; align-items: center; white-space: nowrap; }
.bar-field label { margin: 0; font-size: .85rem; color: var(--muted); }
.board-bar input[type="date"] { width: auto; }
.board-note { font-size: .8rem; color: var(--muted); }
.legend { display: flex; gap: .9rem; font-size: .76rem; color: var(--muted); flex-wrap: wrap; }
.legend span::before { content: ""; display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: .35rem; vertical-align: -1px; }
.legend .lg-free::before { background: #e8f4ec; border: 1px solid #bfe1cb; }
.legend .lg-busy::before { background: repeating-linear-gradient(135deg, #e4e7ee 0 3px, #d8dce5 3px 6px); border: 1px solid #b9c0cc; }
.legend .lg-locked::before { background: #fdf1dd; border: 1px solid #f0d9ae; }
.legend .lg-pub::before { background: #e3ecfc; border: 1px solid #bcd2f5; }

/* Room for a compact block drawn from the last row's end. */
.board-scroll { overflow-x: auto; padding-bottom: var(--block-min); }
/* One area column plus the hour gutter: the old 560px floor was for the
   days when every area was drawn side by side. */
table.board { border-collapse: collapse; min-width: 240px; width: 100%; font-size: .8rem; }
table.board th, table.board td { border: 1px solid var(--line); padding: 0; }
table.board th { background: #fbfcfe; padding: .45rem .5rem; font-size: .74rem; color: var(--muted); }
table.board th.hour { width: 52px; }
/* Timeline geometry the script reads too (TL): a row's height, and the
   smallest block drawn — one label line (.68rem × 1.15 ≈ 12.5px) plus 2px.
   Only the drawing uses the minimum; times and durations never change. */
/* --block-gap: the least free space drawn between two blocks for them to
   read as separate; blocks closer than that are drawn as one group. */
:root { --row-h: 34px; --block-min: 15px; --block-gap: 4px; }
td.slot { height: var(--row-h); min-width: 110px; background: #f3f4f7; }
/* The time label must not stretch its row past --row-h (its padding once
   made rows taller than the blocks' geometry assumed). */
table.board tbody th.hour { height: var(--row-h); padding-top: 0; padding-bottom: 0; line-height: 1.2; }
td.slot.free { background: #e8f4ec; }
/* Rows outside the hours customers book (the admin board's night, D11).
   An inset shadow rather than a background, so a state's own background
   (free, unknown, claimed) never wipes it out. */
td.slot.off-hours { box-shadow: inset 0 0 0 100vmax rgba(20, 24, 33, .05); }
td.slot.unknown { background: repeating-linear-gradient(45deg, #f3f4f7, #f3f4f7 6px, #ebedf1 6px, #ebedf1 12px); }
td.slot .lk {
  display: flex; flex-direction: column; justify-content: center; gap: .05rem;
  height: 100%; padding: .15rem .45rem; cursor: pointer; border-radius: 0;
  font-size: .72rem; line-height: 1.25; overflow: hidden;
}
td.slot.locked { background: #fdf1dd; }
td.slot.published { background: #e3ecfc; }
td.slot .lk .who { color: var(--muted); font-size: .68rem; }
button.small {
  padding: .35rem .8rem; font-size: .8rem; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel); color: var(--accent);
  font-family: inherit; font-weight: 600;
}
/* Hover keeps each button's own background: the pages' plain `button:hover`
   (their main blue) comes after this file. */
button.small:hover { border-color: var(--accent); background: var(--panel); }
button.small.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
button.small.primary:hover { opacity: .92; background: var(--accent); }
button.small.danger { color: var(--bad); }
button.small:disabled { opacity: .5; cursor: default; }
/* Blocks sit on the row's time axis: top and height are the block's own
   start and duration as a share of the row's interval (inline style), so a
   15 s spot is 15 s tall wherever that is at least --block-min. Shorter
   than that at this zoom, it is drawn --block-min tall from its true start
   ("compact"), so it stays one readable, clickable block. z-index lets a
   compact block near a row's end show over the next row. */
td.slot { position: relative; }
/* The layer takes no clicks itself (a plain lock's label under it must stay
   clickable); the blocks on it do. */
td.slot .airings { position: absolute; inset: 0; pointer-events: none; }
td.slot .airings > .airing:not(.drop-preview):not(.band) { pointer-events: auto; }
td.slot .airing {
  position: absolute; left: 0; right: 0; box-sizing: border-box; z-index: 1;
  background: #fdf1dd; border-left: 2px solid #d9a441; border-radius: 3px;
  white-space: nowrap; font-size: .68rem; line-height: 1.15; padding: 0 .35rem; overflow: hidden;
}
td.slot .airing.compact { height: var(--block-min); display: flex; align-items: center; }
td.slot .lk.airing { align-items: flex-start; }
/* Several airings (or bookings) too short to draw one by one at this zoom,
   drawn as one block from the first start to the last end. */
td.slot .airing.group > span { font-weight: 600; }
/* A combined block of several ads (the single-column layout) with some
   read-only time inside: a grey edge says so (a border, so the selection
   halo and the CMS underline still show). */
td.slot .airing.mix.part-busy { border-right: 6px solid #c3c9d4; }
/* A label on a piece shorter than a line, running down over the rest of
   its own block (clipped sideways, never into the next lane). */
td.slot .airings > .airing.spill { overflow-x: clip; overflow-y: visible; z-index: 4; justify-content: flex-start; }
@supports not (overflow-x: clip) { td.slot .airings > .airing.spill { overflow: visible; } }
/* The window of a claim that holds all of it — one made before its airings
   were stored. A collection laid out by Step 1 blocks only its airings, so
   it has no band and the gaps between them stay free. */
td.slot .airing.band {
  z-index: 0; left: 0; right: 0; padding: 0; border-radius: 0;
  background: rgba(217, 164, 65, .13); border-left: 2px dotted #d9a441;
}
td.slot .airing.band.pub { background: rgba(46, 106, 208, .14); border-left-color: #8fb0e6; }
td.slot .airing.band.drag-source { opacity: .35; }
/* A plain Lock-in claim: one block over its whole window. */
td.slot .lk.airing.plain { justify-content: flex-start; padding-top: .1rem; }
td.slot .lk.airing.plain.compact { justify-content: center; padding-top: 0; }
td.slot .airing.plain.publishing { background: #eef1f6; border-left-color: #8d97a8; }
td.slot .airing.plain .who { color: var(--muted); font-size: .66rem; }
td.slot.claimed { background: #f6f4ef; }
td.slot .airing.pub { background: #e3ecfc; border-left-color: var(--accent); }
td.slot .airing:hover { z-index: 3; outline: 1px solid var(--accent); outline-offset: -1px; }
td.slot .airing.selected { z-index: 2; outline: 2px solid var(--accent); outline-offset: -2px; }
td.slot .airing.draggable { cursor: grab; touch-action: manipulation; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.drag-armed { outline: 2px solid var(--accent) !important; outline-offset: -2px; }
td.slot .airing.drag-source { opacity: .35; }
/* Read-only: booked or unavailable on his calendar, or another ad's later
   claim. Same positioning as airings; never draggable. */
td.slot .airing.busy {
  background: repeating-linear-gradient(135deg, #e4e7ee 0 6px, #d8dce5 6px 12px);
  border-left-color: #7d879b; color: #3f4759; cursor: not-allowed;
}
td.slot .airing.busy.claim {
  background: repeating-linear-gradient(135deg, #f3ede1 0 6px, #e9dfcb 6px 12px);
  border-left-color: #a88a52;
}
td.slot .airing.busy:hover { outline-color: #7d879b; }
/* Where a drag would land, as the airings resolve around what is already
   there: dashed in the accent colour at their ideal second, amber where
   collision resolution had to move one later. */
td.slot .airing.drop-preview {
  z-index: 4; pointer-events: none; background: rgba(46, 106, 208, .16);
  border: 1px dashed var(--accent); border-left-width: 2px; color: var(--accent);
}
td.slot .airing.drop-preview.moved {
  z-index: 5; background: rgba(163, 116, 22, .22); border-color: var(--warn); color: var(--warn); font-weight: 600;
}
/* A spot longer than its row continues into the next cell. */
td.slot .airing.cont-up { border-top-left-radius: 0; border-top-right-radius: 0; }
td.slot .airing.cont-down { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
/* The block under the pointer while dragging. */
#drag-ghost {
  position: fixed; z-index: 80; pointer-events: none; min-width: 150px; max-width: 260px;
  background: #fdf1dd; border: 1px solid #d9a441; border-left-width: 3px; border-radius: 4px;
  box-shadow: 0 8px 22px rgba(20, 40, 80, .22); font-size: .72rem; line-height: 1.3; padding: .25rem .5rem;
}
#drag-ghost .why { color: var(--muted); white-space: normal; }
#drag-ghost.invalid { background: #fbeeee; border-color: var(--bad); }
#drag-ghost.invalid .why { color: var(--bad); }
body.board-dragging, body.board-dragging * { -webkit-user-select: none; user-select: none; cursor: grabbing !important; }
/* The corner panel must not hide drop targets under it mid-drag. */
body.board-dragging #drag-panel { pointer-events: none; opacity: .6; }
body.board-dragging.drop-invalid, body.board-dragging.drop-invalid * { cursor: not-allowed !important; }
/* Second-level zoom: time labels carry seconds; whole minutes and hours get
   a stronger rule (inset shadow, so row heights stay untouched). */
table.board.sec th.hour { width: 66px; }
table.board.sec tr.min-mark > * { box-shadow: inset 0 1px 0 #c3cad8; }
table.board.sec tr.hour-mark > * { box-shadow: inset 0 2px 0 #8f9bb3; }
/* the right-corner panel shown while dragging / after a drop */
/* Capped to the viewport: a lock's CMS state and notes can run long, and a
   fixed panel taller than the screen hides its own buttons. */
#drag-panel {
  position: fixed; right: 18px; bottom: 18px; z-index: 60; width: 300px;
  max-width: calc(100vw - 36px); max-height: calc(100vh - 36px); overflow-y: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 14px 40px rgba(20,40,80,.18); padding: 1rem 1.1rem;
  font-size: .84rem;
}
#drag-panel h4 { font-size: .95rem; margin-bottom: .5rem; }
#drag-panel .dp-meta { color: var(--muted); font-size: .8rem; margin-bottom: .2rem; }
#drag-panel .dp-plan { margin: .6rem 0; max-height: 150px; overflow:auto; font-variant-numeric: tabular-nums; }
#drag-panel .dp-plan div { padding: .1rem 0; }
#drag-panel .dp-hint { color: var(--muted); font-size: .78rem; }
#drag-panel .row2 { display: flex; gap: .5rem; justify-content: flex-end; margin-top: .8rem; }
#drag-panel .dp-result { font-size: .8rem; margin-top: .6rem; white-space: pre-line; }
/* The lock's state on Ko Willy's side: publish lease, creative, airings. */
#drag-panel .dp-cms {
  margin: .55rem 0 .2rem; padding: .45rem .6rem; border-radius: 8px;
  font-size: .79rem; line-height: 1.4; background: #f2f5f9; color: var(--text);
}
#drag-panel .dp-cms.ok { background: #f0f9f4; color: var(--ok); }
#drag-panel .dp-cms.warn { background: #fdf5e6; color: var(--warn); }
#drag-panel .dp-cms.bad { background: #fbf0f0; color: var(--bad); }
#drag-panel .dp-cms-actions { display: flex; justify-content: flex-end; margin: .1rem 0 .3rem; }
#drag-panel .dp-note { font-size: .76rem; color: var(--warn); margin-bottom: .2rem; white-space: pre-line; }
td.slot.publishing { background: #eef1f6; }
td.slot .airing.cms-bad, td.slot.cms-bad .lk { box-shadow: inset 0 -2px 0 var(--bad); }
td.slot .airing.cms-warn, td.slot.cms-warn .lk { box-shadow: inset 0 -2px 0 var(--warn); }
button.small.danger:hover { border-color: var(--bad); }
/* A destructive button after its first click, waiting for the second. */
button.small.danger.armed, button.small.danger.armed:hover { background: var(--bad); color: #fff; border-color: var(--bad); }
/* dialogs and the toast */
.wf-overlay {
  position: fixed; inset: 0; background: rgba(15, 20, 30, .45); z-index: 70;
  display: flex; align-items: center; justify-content: center; padding: 1rem;
}
.wf-dialog {
  background: var(--panel); border-radius: 14px; padding: 1.3rem 1.4rem; width: 100%; max-width: 470px;
  max-height: calc(100vh - 2rem); overflow: auto; box-shadow: 0 18px 50px rgba(20, 40, 80, .25);
}
.wf-dialog h3 { font-size: 1rem; margin-bottom: .6rem; }
.wf-dialog p { font-size: .86rem; color: var(--muted); margin-bottom: .6rem; white-space: pre-line; }
.wf-dialog .buttons { display: flex; justify-content: flex-end; gap: .5rem; margin-top: 1rem; }
.wf-dialog input[type="file"] { width: 100%; padding: .5rem; }
.wf-dialog .progress { height: 6px; border-radius: 6px; background: #eef1f6; overflow: hidden; margin-top: .7rem; }
.wf-dialog .progress > div { height: 100%; width: 0; background: var(--accent); transition: width .15s; }
.wf-dialog .result { font-size: .84rem; margin-top: .6rem; white-space: pre-line; }
button.danger-fill { background: var(--bad); }
button.danger-fill:hover { background: #a93a3a; }
#wf-toast {
  position: fixed; left: 18px; bottom: 18px; z-index: 75; max-width: min(420px, calc(100vw - 36px));
  background: #1f2633; color: #fff; border-radius: 12px; padding: .7rem .9rem; font-size: .85rem;
  box-shadow: 0 12px 30px rgba(20, 40, 80, .25); display: flex; gap: .7rem; align-items: center;
}
#wf-toast.bad { background: #7d2a2a; }
#wf-toast button { background: none; border: 1px solid rgba(255,255,255,.35); padding: .25rem .6rem; font-size: .78rem; }

/* ---------- zoom and the admin page's selection ---------- */
/* One finger scrolls the board; two pinch-zoom it (static/tt/board.js). */
.board-scroll { touch-action: pan-x pan-y; }
/* An airing an admin selected (static/tt/admin-board.js). */
td.slot .airing.sel { z-index: 3; outline: 2px solid #e8590c; outline-offset: -2px; box-shadow: 0 0 0 3px rgba(232, 89, 12, .2); }
td.slot .airing.sel.moving { opacity: .35; }
.tt-lasso { position: absolute; z-index: 6; pointer-events: none; border: 1px dashed #e8590c; background: rgba(232, 89, 12, .08); }
td.slot.tt-active-cell { box-shadow: inset 0 0 0 2px #e8590c; }
td.slot .airing.drop-preview.invalid { background: #fbeeee; border-left-color: var(--bad); }
/* The admin's confirmation panel: the corner panel's look, centred. */
.tt-panel {
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: .9rem 1rem;
  width: 100%; max-width: 420px; max-height: calc(100vh - 2rem); overflow: auto;
  box-shadow: 0 18px 50px rgba(20, 40, 80, .25); font-size: .84rem;
}
.tt-panel h4 { font-size: .95rem; margin-bottom: .5rem; }
.tt-panel .dp-meta { color: var(--muted); font-size: .8rem; margin-bottom: .2rem; }
.tt-panel .dp-plan { margin: .6rem 0; max-height: 180px; overflow: auto; font-variant-numeric: tabular-nums; }
.tt-panel .dp-plan div { padding: .1rem 0; }
.tt-panel .dp-hint { color: var(--muted); font-size: .78rem; white-space: pre-line; }
.tt-panel .dp-warn { color: var(--bad); font-size: .8rem; font-weight: 600; margin-top: .4rem; }
.tt-panel .row2 { display: flex; gap: .5rem; justify-content: flex-end; margin-top: .8rem; }
.tt-panel .dp-result { font-size: .8rem; margin-top: .6rem; white-space: pre-line; }
