:root { --uri: #365f91; --busy: #cfe2f3; --line: #ccc; }
* { box-sizing: border-box; }
body { font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
       margin: 0; color: #222; background: #fff; line-height: 1.45; }
header { background: var(--uri); color: #fff; padding: 1rem 1.5rem; }
header h1 { margin: 0; font-size: 1.35rem; font-weight: 600; text-align: center; }
main { max-width: 1150px; margin: 1.5rem auto; padding: 0 1.25rem; }
footer { border-top: 1px solid var(--line); margin-top: 2.5rem; padding: 1rem 1.5rem;
         font-size: .85rem; color: #666; text-align: center; }

.notice { padding: .7rem 1rem; border-radius: 4px; font-weight: 600; }
.notice.ok  { background: #e8f6ec; border-left: 4px solid #2a7a3b; color: #1e5c2c; }
.notice.err { background: #fdecea; border-left: 4px solid #c00; color: #8a1c14; }

.picker { margin: 1rem 0; }
.picker label { font-weight: 600; margin-right: .5rem; }
.picker select { font-size: 1rem; padding: .35rem .5rem; max-width: 30rem; }
.meta { color: #555; font-size: .92rem; }

h2 { color: var(--uri); margin-top: 2rem; }
/* Booking-form styling (layout, labels, inputs, button) is defined once in the
   "Three deliberate rows" block further down. An earlier duplicate set of these
   rules lived here and silently overrode parts of it; removed. */

/* ---- admin ---- */
ul.stats { list-style: none; display: flex; flex-wrap: wrap; gap: 1.5rem;
           padding: .8rem 1rem; margin: 1rem 0; background: #f4f7fb;
           border: 1px solid #dde5ef; border-radius: 4px; font-size: .9rem; }
ul.stats b { color: var(--uri); font-size: 1.1rem; }

table.list { border-collapse: collapse; width: 100%; font-size: .88rem; margin-bottom: 2rem; }
table.list th, table.list td { border-bottom: 1px solid var(--line);
                               padding: .5rem .6rem; text-align: left; vertical-align: top; }
table.list thead th { background: #eef2f7; font-size: .8rem; text-transform: uppercase;
                      letter-spacing: .04em; color: #4a5a6a; }
table.list tr.stale td { background: #fff6f5; }
table.list form { margin: 0; }
.mono { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .82rem; }

button.danger { background: #fff; color: #a4261c; border: 1px solid #d9a5a0;
                border-radius: 3px; padding: .25rem .6rem; font-size: .8rem; cursor: pointer; }
button.danger:hover { background: #a4261c; color: #fff; }

form.rowform { border: 1px solid var(--line); border-radius: 4px;
               padding: .8rem 1rem; margin-bottom: .8rem; }
form.rowform.retired { background: #fafafa; opacity: .75; }
form.rowform .fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
                       gap: .6rem; margin-bottom: .7rem; }
form.rowform label { display: flex; flex-direction: column; font-weight: 600; font-size: .78rem;
                     color: #4a5a6a; }
form.rowform label.chk { flex-direction: row; align-items: center; gap: .4rem; }
form.rowform input, form.rowform select { font-size: .9rem; padding: .35rem; margin-top: .2rem;
                                          border: 1px solid #aaa; border-radius: 3px; }
form.rowform input:disabled { background: #f0f0f0; color: #555; font-weight: 700; }
form.rowform button { background: var(--uri); color: #fff; border: 0; border-radius: 3px;
                      padding: .35rem 1rem; font-size: .85rem; font-weight: 600; cursor: pointer; }
a.preview { margin-left: .8rem; font-size: .85rem; color: var(--uri); }

/* ---- week pagination and booking form, both at the top of the page ---- */
.weekbar { display:flex; align-items:center; gap:.7rem; flex-wrap:wrap;
           background:#f4f7fb; border:1px solid #dde5ef; border-radius:5px;
           padding:.7rem .9rem; margin:0 0 .6rem; }
.weekbar .btn { background:var(--uri); color:#fff; text-decoration:none;
                padding:.4rem .9rem; border-radius:4px; font-size:.88rem; font-weight:600; }
.weekbar .btn:hover { background:#2b4c74; }
.weekbar .btn.today { background:#fff; color:var(--uri); border:1px solid var(--uri); }
.weekbar .weeklabel { font-weight:700; font-size:1rem; color:#1f3555; flex:1 1 auto; text-align:center; }
.weekbar form.jump { display:flex; align-items:center; gap:.4rem; margin:0; }
.weekbar form.jump label { font-size:.82rem; font-weight:600; color:#4a5a6a; }
.weekbar form.jump input { font-size:.88rem; padding:.3rem; border:1px solid #aaa; border-radius:3px; }
.weekbar form.jump button { background:#fff; color:var(--uri); border:1px solid var(--uri);
                            border-radius:3px; padding:.3rem .7rem; font-size:.85rem;
                            font-weight:600; cursor:pointer; }

/* Tinted panel with a shadow so the form stands out from the white page.
   Inputs stay white, so they read clearly against the tint. */
.bookbox { border:1px solid #b9c9dd; border-left:5px solid var(--uri);
           border-radius:5px; margin-bottom:1.6rem; background:#e8eff8;
           box-shadow:0 2px 6px rgba(31,53,85,.14); }
form.book input, form.book select { background:#fff; }
/* Collapsed: only the summary bar shows. Expanded: padding appears below it. */
.bookbox > summary { cursor:pointer; padding:.7rem 1.1rem; font-size:1.05rem;
                     font-weight:600; color:var(--uri); list-style:none;
                     display:flex; align-items:baseline; gap:.6rem;
                     flex-wrap:wrap; user-select:none; }
.bookbox > summary::-webkit-details-marker { display:none; }
.bookbox > summary:hover { background:#dbe6f3; }
.bookbox > summary:focus-visible { outline:2px solid var(--uri); outline-offset:-2px; }
/* Disclosure triangle, rotated when open. */
.bookbox > summary::before { content:"\25B8"; display:inline-block;
                             transition:transform .15s ease; font-size:.9em; }
.bookbox[open] > summary::before { transform:rotate(90deg); }
.bookbox > summary .sumhint { font-weight:400; font-size:.8rem; color:#6b7888; }
.bookbox[open] > summary { border-bottom:1px solid #b9c9dd; margin-bottom:.9rem; }
.bookbox > *:not(summary) { margin-left:1.1rem; margin-right:1.1rem; }
.bookbox > form.book { margin-bottom:1.1rem; }
/* Three deliberate rows, not an opportunistic wrap:
     1. what and when  - resource, date, start, end
     2. event/purpose  - full width, it is the longest free-text field
     3. who            - name, email, phone
   Widths within a row are sized to measured content (n=51,165 reservations):
   resource names reach 34 chars, event titles p95=34 but max 163, names
   p95=19, emails p95=23, phones p95=12. Times are always 8 chars
   ("12:30 pm") and dates are a fixed-width picker. */
form.book .fields { display:flex; flex-wrap:wrap; align-items:flex-end;
                    gap:.7rem .8rem; margin-bottom:.9rem; }
/* Note on specificity: these are written as `form.book .fields > label.f-x`
   rather than a bare `.f-x`, because `form.book .fields > label` below scores
   0,2,2 and would otherwise override a plain class selector's flex value. */
form.book .fields > label { flex:0 1 auto; }

/* Row 1: resource, date, start, end */
form.book .fields > label.f-resource { flex:1 1 20rem; min-width:16rem; }
form.book .fields > label.f-date     { flex:0 0 9.5rem; }
form.book .fields > label.f-time     { flex:0 0 7.5rem; }
form.book .fields > label.f-recur    { flex:1 1 15rem; min-width:13rem; }

/* Row 2: event/purpose alone, full width. It holds the most text on the
   form (max 163 chars in the imported data), so it gets its own line. */
form.book .fields > label.f-title    { flex:1 1 100%; }

/* Row 3: name, email, phone share a line. */
form.book .fields > label.f-name     { flex:1 1 14rem; min-width:11rem; }
form.book .fields > label.f-email    { flex:1 1 16rem; min-width:12rem; }
form.book .fields > label.f-phone    { flex:0 1 11rem; min-width:9rem; }
/* Reserve button rides the end of row 3, pushed to the far right. */
form.book .fields > .f-submit { flex:0 0 auto; margin-left:auto; align-self:flex-end; }
form.book .fields > .f-submit button { margin:0; }

/* Below ~620px the row layout stops helping; go full width. */
@media (max-width:620px) {
  form.book .fields > label,
  form.book .fields > label[class] { flex:1 1 100%; min-width:0; }
  form.book .fields > .f-submit { flex:1 1 100%; margin-left:0; }
  form.book .fields > .f-submit button { width:100%; }
}

/* The admin login reuses form.book but has a single unclassed field, which
   would otherwise collapse in the flex row. Give it a sensible width. */
form.book .fields > label:not([class]) { flex:0 1 20rem; min-width:14rem; }
form.book label { display:flex; flex-direction:column; font-weight:600;
                  font-size:.8rem; color:#4a5a6a; }
form.book input, form.book select { font-size:.92rem; padding:.4rem; margin-top:.22rem;
                                    border:1px solid #aaa; border-radius:3px; }
form.book button { background:var(--uri); color:#fff; border:0; border-radius:4px;
                   padding:.55rem 1.4rem; font-size:.95rem; font-weight:600; cursor:pointer; }
form.book button:hover { background:#2b4c74; }
form.book .hint { font-size:.82rem; color:#667; margin:0; }

/* ---- one table per day, every resource as a row ---- */
.daygrid { margin:1.6rem 0 2rem; }
.daygrid h2 { font-size:1.02rem; color:#1f3555; background:#f0f0f0;
              border:1px solid #d4d4d4; border-bottom:0; margin:0;
              padding:.5rem .8rem; border-radius:4px 4px 0 0; }
.daygrid.today h2 { background:var(--uri); color:#fff; border-color:var(--uri); }
.daygrid .badge { background:#fff; color:var(--uri); font-size:.7rem; font-weight:700;
                  padding:.1rem .45rem; border-radius:3px; margin-left:.5rem;
                  vertical-align:middle; }
.scroller { overflow-x:auto; border:1px solid #d4d4d4; border-top:0; }

table.week { border-collapse:collapse; width:100%; table-layout:fixed;
             font-size:.75rem; min-width:56rem; }
table.week th, table.week td { border:1px solid #d9d9d9; }
table.week thead th { background:#f0f0f0; font-weight:600; font-size:.72rem;
                      color:#333; padding:.3rem 0; text-align:center; }
table.week th.resname { width:13rem; background:#f0f0f0; text-align:left;
                        font-weight:600; padding:.35rem .5rem; font-size:.76rem;
                        white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
                        position:sticky; left:0; z-index:1; }
table.week tbody tr:hover th.resname { background:#e7edf5; }
table.week td { height:1.8rem; padding:0; }
td.f { background:#fff; }
td.f a { display:block; width:100%; height:1.8rem; }
td.f a:hover { background:#fff3b0; outline:1px solid #d9b500; }
td.b { background:#ffcece; font-size:.72rem; padding:0 .3rem; text-align:center;
          white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
          font-weight:600; color:#7a2018; }
.sr { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
.legend { font-size:.78rem; color:#777; margin:.4rem 0 0; }

/* ---- day tabs ---- */
.daytabs { display:flex; gap:2px; margin:0; border-bottom:2px solid var(--uri);
           flex-wrap:wrap; }
.daytabs .tab { display:flex; flex-direction:column; align-items:center;
                min-width:5.2rem; padding:.45rem .7rem .4rem; text-decoration:none;
                background:#eef2f7; color:#3d4b5c; border:1px solid #cbd6e4;
                border-bottom:0; border-radius:5px 5px 0 0; position:relative;
                line-height:1.25; }
.daytabs .tab:hover { background:#e2eaf4; color:var(--uri); }
.daytabs .tab .dow  { font-weight:700; font-size:.88rem; }
.daytabs .tab .dnum { font-size:.72rem; color:#6b7888; }
.daytabs .tab.on { background:var(--uri); color:#fff; border-color:var(--uri);
                   margin-bottom:-2px; padding-bottom:.5rem; }
.daytabs .tab.on .dnum { color:#cfe0f5; }
.daytabs .tab.isnow:not(.on) { box-shadow:inset 0 3px 0 #d9b500; }
.daytabs .tab .cnt { position:absolute; top:.15rem; right:.3rem; background:#c0392b;
                     color:#fff; font-size:.62rem; font-weight:700; line-height:1;
                     padding:.12rem .3rem; border-radius:7px; }
.daytabs .tab.on .cnt { background:#fff; color:#c0392b; }

/* ---- instant hover detail panel (replaces native title= tooltips) ---- */
#tip { position:fixed; z-index:50; display:none; pointer-events:none;
       max-width:30rem; background:#1f2b38; color:#fff; border-radius:6px;
       padding:.75rem 1rem; font-size:1rem; line-height:1.45;
       box-shadow:0 4px 16px rgba(0,0,0,.34); }
#tip.on { display:block; }
#tip b { display:block; font-size:1.15rem; margin-bottom:.3rem; }
#tip b.tfree { color:#8fe0a4; }
#tip .tw { display:block; font-size:1.05rem; font-weight:600; color:#ffd98a;
           font-variant-numeric:tabular-nums; }
#tip .tr { display:block; font-size:.95rem; color:#b9cbe0; margin-top:.1rem; }
#tip .tn { display:block; font-size:.95rem; color:#dfe7f0; font-style:italic;
           margin-top:.25rem; }

/* ---- attention animation when a free cell is clicked ---- */
/* The booking form can be well above the fold, so a click needs a visible
   response. Three cues: the box pulses, the filled fields glow, and a
   confirmation line pops in. */
/* Red, slow, three full pulses so it is hard to miss. */
@keyframes pulseBox {
  0%   { box-shadow:0 0 0 0   rgba(192,57,43,.60); border-left-color:#c0392b; }
  16%  { box-shadow:0 0 0 12px rgba(192,57,43,0);  border-left-color:#e74c3c; }
  33%  { box-shadow:0 0 0 0   rgba(192,57,43,.55); border-left-color:#c0392b; }
  50%  { box-shadow:0 0 0 12px rgba(192,57,43,0);  border-left-color:#e74c3c; }
  66%  { box-shadow:0 0 0 0   rgba(192,57,43,.50); border-left-color:#c0392b; }
  83%  { box-shadow:0 0 0 12px rgba(192,57,43,0);  border-left-color:#e74c3c; }
  100% { box-shadow:0 0 0 0   rgba(192,57,43,0);   border-left-color:var(--uri); }
}
.bookbox.pulse { animation:pulseBox 3.6s ease-out; }

/* Yellow field glow pulses several times, then settles back to normal. */
@keyframes fieldGlow {
  0%   { background:#fff2a8; border-color:#d9b500; box-shadow:0 0 0 3px rgba(217,181,0,.45); }
  14%  { background:#fffdf2; border-color:#e0cb6a; box-shadow:0 0 0 1px rgba(217,181,0,.12); }
  28%  { background:#fff2a8; border-color:#d9b500; box-shadow:0 0 0 3px rgba(217,181,0,.45); }
  42%  { background:#fffdf2; border-color:#e0cb6a; box-shadow:0 0 0 1px rgba(217,181,0,.12); }
  56%  { background:#fff2a8; border-color:#d9b500; box-shadow:0 0 0 3px rgba(217,181,0,.45); }
  75%  { background:#fff8cf; border-color:#d9b500; box-shadow:0 0 0 2px rgba(217,181,0,.22); }
  100% { background:#fff;    border-color:#aaa;    box-shadow:none; }
}
form.book .filled { animation:fieldGlow 3.6s ease-out; }


/* Respect a user's reduced-motion preference. */
@media (prefers-reduced-motion: reduce) {
  .bookbox.pulse, form.book .filled { animation:none; }
}

/* ---- click-to-reserve arrow ---- */
/* Fixed overlay spanning the viewport, so the SVG coordinate space matches
   getBoundingClientRect() output. pointer-events:none keeps the grid clickable
   underneath. */
#arrow { position:fixed; inset:0; width:100vw; height:100vh; z-index:45;
         pointer-events:none; opacity:0; transition:opacity .18s ease-out; }
#arrow.on { opacity:1; }
#arrowpath { fill:none; stroke:#c0392b; stroke-width:2.5; stroke-linecap:round;
             stroke-dasharray:7 5; animation:arrowCrawl 1s linear infinite; }

/* Slow dash crawl along the line, which reads as direction of travel. */
@keyframes arrowCrawl { to { stroke-dashoffset:-24; } }

@media (prefers-reduced-motion: reduce) {
  #arrow { display:none; }
}

/* ---- cursor ---- */
/* Table text would otherwise show an I-beam, which suggests the text is
   selectable content rather than a schedule to click. Keep a plain arrow
   everywhere in the grid, including over booked-block labels and the
   resource names in the row headers. */
table.week,
table.week th,
table.week td,
table.week th.resname,
table.week th.resname span,
td.b,
#tip, #tip * {
  cursor: default;
}
/* Free cells remain obviously actionable. */
td.f a { cursor: pointer; }

/* ---- editing an existing reservation ---- */
/* Booked blocks the current user owns are clickable; others are inert. */
td.b.mine { cursor:pointer; }
td.b.mine a { color:inherit; text-decoration:none; display:block;
              width:100%; height:100%; }
td.b.mine:hover { background:#ffb3b3; outline:2px solid #c0392b; outline-offset:-2px; }

/* Edit mode is visually distinct so it cannot be mistaken for a new booking. */
.bookbox.editing { border-left-color:#b8860b; border-color:#dcc98f; background:#fbf3dc; }
.bookbox.editing > summary { color:#8a6400; }

form.cancelform { display:flex; align-items:center; gap:1rem;
                  margin:0 1.1rem 1.1rem; padding-top:.7rem;
                  border-top:1px dashed #cdb97a; }
form.cancelform button.danger { background:#fff; color:#a4261c;
                                border:1px solid #d9a5a0; border-radius:3px;
                                padding:.4rem .9rem; font-size:.88rem;
                                font-weight:600; cursor:pointer; }
form.cancelform button.danger:hover { background:#a4261c; color:#fff; }
form.cancelform a.discard { font-size:.85rem; color:var(--uri); }

/* Partial success, e.g. a recurring series where some dates were taken. */
.notice.warn { background:#fff8e1; border-left:4px solid #b8860b; color:#6b4f00; }

/* One form, two modes. The server renders both labels; the .editing class
   on .bookbox picks which set shows, so JS can switch modes without a
   reload (see toNewMode in index.php). */
.bookbox .for-edit { display:none; }
.bookbox.editing .for-edit { display:inline; }
.bookbox.editing .for-new  { display:none !important; }
