/* ─────────────────────────────────────────────────────────────────────────
   DATEPICKER · FLOATING LABEL                              v1.025
   https://turnerlee.com/shared/forms/v1/datepicker-float.css?v=1.025

   The date field that sits in a row with .form-floating text inputs and
   selects without breaking the rhythm. Same 4.5rem box, same 1.25rem
   gutter, label inside at the top-left, field still typeable, calendar
   still clickable.

   Measured 2026-09-16 05:40 MDT on craigwhitlock.com/ops/tickets, 1100 and
   390 wide: text · date · select · date pitch 101.1 / 101.2 / 101.2 px.
   Icon panel sits on the input's border box exactly — dTop 0, dBottom 0,
   dRight 0 — in flow layout and as a grid item.

   MARKUP
     <div class="form-floating datepicker-input">
       <input type="date" id="listedOn" class="form-control" placeholder="Listed on">
       <label for="listedOn">Listed on</label>
       <div class="datepicker-input__icon"><i class="fa fa-calendar"></i></div>
       <button type="button" class="datepicker-input__clear" data-dp-clear>Clear</button>
     </div>

   The label starts floated and stays floated, because a date input never
   matches :placeholder-shown — so Bootstrap's own
   `.form-control:not(:placeholder-shown) ~ label` rule is already true on
   it. Nothing here re-implements the float; it only clears room for the
   icon panel and places the clear control.

   datepicker-float.js is optional. With it, an empty field mutes its
   native mm/dd/yyyy and drops CLEAR. Without it, both simply always show.

   The OLD label-above pattern (.datepicker-input with no .form-floating)
   is untouched — every selector below requires both classes.
   ───────────────────────────────────────────────────────────────────── */

/* BOOTSTRAP 5's FLOAT, CARRIED FOR A BOOTSTRAP 4 PAGE, v1.024.
   Everything below assumes Bootstrap 5's .form-floating. webbortho.com's trackers
   load Bootstrap 4.4.1, which has no .form-floating at all, so the label fell under
   the field and the icon panel ran 65px past it - measured 2026-09-25 on
   webbortho.com/control-contact-tracker. These are Bootstrap 5.1.3's own rules,
   copied verbatim (the .form-select lines dropped - this component has no select),
   with the selector wrapped in :where() so each one is exactly one level weaker
   than Bootstrap 5's. On every Bootstrap 5 page Bootstrap's own rule, and any site
   sheet above it, still wins and nothing changes; on a Bootstrap 4 page these beat
   BS4's bare .form-control / label by source order and supply the float. */
:where(.form-floating.datepicker-input) > .form-control {
  height: calc(3.5rem + 2px);
  line-height: 1.25;
}
:where(.form-floating.datepicker-input) > label {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  padding: 1rem 0.75rem;
  pointer-events: none;
  border: 1px solid transparent;
  transform-origin: 0 0;
  transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;
}
:where(.form-floating.datepicker-input) > .form-control {
  padding: 1rem 0.75rem;
}
:where(.form-floating.datepicker-input) > .form-control::-moz-placeholder {
  color: transparent;
}
:where(.form-floating.datepicker-input) > .form-control::placeholder {
  color: transparent;
}
:where(.form-floating.datepicker-input) > .form-control:not(:-moz-placeholder-shown) {
  padding-top: 1.625rem;
  padding-bottom: 0.625rem;
}
:where(.form-floating.datepicker-input) > .form-control:focus, :where(.form-floating.datepicker-input) > .form-control:not(:placeholder-shown) {
  padding-top: 1.625rem;
  padding-bottom: 0.625rem;
}
:where(.form-floating.datepicker-input) > .form-control:-webkit-autofill {
  padding-top: 1.625rem;
  padding-bottom: 0.625rem;
}
:where(.form-floating.datepicker-input) > .form-control:not(:-moz-placeholder-shown) ~ label {
  opacity: 0.65;
  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
}
:where(.form-floating.datepicker-input) > .form-control:focus ~ label,
:where(.form-floating.datepicker-input) > .form-control:not(:placeholder-shown) ~ label {
  opacity: 0.65;
  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
}
:where(.form-floating.datepicker-input) > .form-control:-webkit-autofill ~ label {
  opacity: 0.65;
  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
}

/* The gutter lives on the WRAPPER, not the input: a child's bottom margin
   escapes a block parent but not a grid item, and that 22px swing is what
   leaves the icon panel 22px short of the bottom edge in flow layout. */
.form-floating.datepicker-input {
  position: relative;
  display: block;
  margin-bottom: 1.25rem;

  /* CLEAR rides the label's line, so it is positioned from the label's INK and
     not from the label's box — the floated label is transform:scale()d, which
     puts those 7px apart. Measured on turnerlee.com/ops/style-guide 2026-09-16
     07:12 MDT with a Range around the label's text node: ink top 11.25px, ink
     left 13.3px, line box 15px, rendered type 11.09px (18.48px scaled 0.6),
     against a 17.6px root. A site whose floated-label scale differs retunes
     these five and nothing else. */
  --dp-icon-w: 45px;
  --dp-label-top: .64rem;      /* 11.25px */
  --dp-label-inset: .76rem;    /* 13.3px  */
  --dp-label-line: .85rem;     /* 15px    */
  --dp-label-font: .63rem;     /* 11.09px */
}

.form-floating.datepicker-input > .form-control {
  margin-bottom: 0;
  padding-left: 10px;              /* the value ink lines up with a text field's, which
                                      sst-styles pins at 10px; a bare date field inherits
                                      Bootstrap's .75rem and sits 3.2px further in */
  padding-right: 55px;             /* clear the 45px icon panel */
  line-height: 1.2 !important;     /* beats input[type=date]{line-height:4.5rem!important} */
}

.form-floating.datepicker-input > label {
  box-sizing: border-box;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* The label is a copy target, so it takes the pointer back from Bootstrap's
     pointer-events:none. Its box is CAPPED to its own ink row — left at the
     default it is the full field height and, scaled, it would swallow clicks
     meant for the date value underneath. */
  height: 2.2rem;
  pointer-events: auto;
  cursor: copy;
  -webkit-user-select: none; -moz-user-select: none; user-select: none;
}

/* The native indicator is gone: our own calendar replaces it, and leaving it
   stretched across the icon panel meant one click opened both. The field is
   still a real date input, so typing and validation are untouched. */
.form-floating.datepicker-input > input[type="date"]::-webkit-calendar-picker-indicator,
.form-floating.datepicker-input > input[type="datetime-local"]::-webkit-calendar-picker-indicator {
  display: none;
}
.form-floating.datepicker-input > input[type="date"]::-webkit-inner-spin-button,
.form-floating.datepicker-input > input[type="date"]::-webkit-clear-button,
.form-floating.datepicker-input > input[type="datetime-local"]::-webkit-inner-spin-button,
.form-floating.datepicker-input > input[type="datetime-local"]::-webkit-clear-button {
  display: none;
}

.form-floating.datepicker-input > .datepicker-input__icon {
  position: absolute;
  top: 0;
  right: 0;
  width: var(--dp-icon-w);
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--color1, #00509F);
  color: var(--sg-icon-on-color1, var(--flexwhite, rgba(255, 255, 255, .92)));
  font-size: 1.25rem;
  line-height: 1;
  border-radius: 0 var(--InputBorderRadius, .25rem) var(--InputBorderRadius, .25rem) 0;
  pointer-events: none;
  z-index: 1;
}
.form-floating.datepicker-input > .datepicker-input__icon i,
.form-floating.datepicker-input > .datepicker-input__icon svg {
  color: var(--sg-icon-on-color1, var(--flexwhite, rgba(255, 255, 255, .92)));
}
.form-floating.datepicker-input > .datepicker-input__icon svg path {
  fill: var(--sg-icon-on-color1, var(--flexwhite, rgba(255, 255, 255, .92)));
}

/* CLEAR rides the label's line, right-aligned against the icon panel, with the
   same inset from its edge that the label has from the left. It is inside the
   field and out of flow, so it still costs zero height. */
.form-floating.datepicker-input > .datepicker-input__clear {
  position: absolute;
  top: var(--dp-label-top);
  right: calc(var(--dp-icon-w) + var(--dp-label-inset));
  height: var(--dp-label-line);
  line-height: var(--dp-label-line);
  padding: 0;
  background: none;
  border: 0;
  border-radius: 2px;
  font-size: var(--dp-label-font);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color1, #00509F);
  opacity: .72;
  cursor: pointer;
  z-index: 2;
}
.form-floating.datepicker-input > .datepicker-input__clear:hover,
.form-floating.datepicker-input > .datepicker-input__clear:focus-visible {
  opacity: 1;
  text-decoration: underline;
}

/* Empty state — set by datepicker-float.js. */
.form-floating.datepicker-input.is-empty > .form-control {
  color: var(--InputPlaceholderColor, rgba(0, 0, 0, .35));
}
.form-floating.datepicker-input.is-empty > .datepicker-input__clear {
  display: none;
}
.form-floating.datepicker-input > .form-control:focus {
  color: var(--InputColorFocus, inherit);
}

/* The icon panel is the popup's trigger, so it takes the pointer back. The
   native indicator is suppressed by the rule above — our calendar replaces it,
   and two pickers fighting over one click is its own bug. */
.form-floating.datepicker-input > .datepicker-input__icon {
  pointer-events: auto;
  cursor: pointer;
}
.form-floating.datepicker-input > .datepicker-input__icon:focus-visible {
  outline: 2px solid var(--color1xl, #66b0da);
  outline-offset: 2px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE CALENDAR POPUP
   Built and appended to document.body by datepicker-float.js, so every rule
   here is a BARE class. A selector scoped to an ancestor the popup does not
   live under matches nothing — and the class still applies, so it looks wired up.

   The brand panel carries .onDrk.onC1, the documented way to say "this surface
   IS brand color 1, put dark-background ink on it". Do NOT reach for
   --flexwhite here: measured on turnerlee.com 2026-09-16 07:40 MDT it resolves
   to #222222 in the page's own light context, and --reverse1 is #0079c1, the
   brand color itself. Inside .onDrk.onC1 the ink tokens re-point and
   var(--FontColor) is correct.
   ═══════════════════════════════════════════════════════════════════════════ */
.dp-cal {
  position: fixed;
  z-index: 2147483000;
  display: flex;
  /* WIDTH IS NOT NEGOTIABLE. Without this the box is shrink-to-fit against the
     space remaining to the right of its own `left`, so a window that is a little
     too narrow squeezed the flex row and overflow:hidden chopped the time column
     off — which read as "the blue field changes width with the month". */
  width: max-content;
  max-width: calc(100vw - 1rem);
  overflow: hidden;
  border-radius: var(--RadiusBrand, 12px);
  background: var(--InputBgColor, #fff);
  box-shadow: 0 12px 34px rgba(0, 0, 0, .22), 0 2px 6px rgba(0, 0, 0, .12);
  /* Website keeps font1 (Hypatia on TurnerLee) for the chrome. /ops /portal
     /control flip to .dp-cal--tool → font0 (Open Sans). The popup is appended
     to body, so it would otherwise miss the ops shell's Open Sans inherit. */
  font-family: var(--font1Family, var(--font2Family, inherit));
  color: var(--FontColor, rgba(0, 0, 0, .85));
  -webkit-user-select: none;   /* WebKit ignores the unprefixed one, so a drag
                                  painted selection across the whole panel */
  -moz-user-select: none;
  user-select: none;

  /* .onC1 and .onDrk RE-DECLARE --color1 itself, not just the ink tokens, so
     `background: var(--color1)` INSIDE the context panel resolves to the
     contrast color and the brand panel paints WHITE. Measured 2026-09-16 07:58
     MDT: rgb(255,255,255). Resolve the brand here, on the one element with no
     context class, and let the finished color inherit down. */
  --dp-brand: var(--color1, #0079C1);
  --dp-brand-d: var(--color1d, #00659f);
  --dp-brand-xl: var(--color1xl, #cfe6f4);
  --dp-brand-f1: var(--color1f1, rgba(0, 121, 193, .1));
}
/* Craig, 2026-09-16: in Operations / Portal / Control the UI face is Open Sans
   — Hypatia on CLEAR / CANCEL / OK / weekday / Time is unreadable there. Same
   contract as ops-dashboard.css. Website (no --tool) keeps font1 above. */
.dp-cal.dp-cal--tool {
  font-family: var(--font0Family, 'Open Sans', -apple-system, BlinkMacSystemFont,
               'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif);
}
.dp-cal * { -webkit-user-select: none; -moz-user-select: none; user-select: none; }
.dp-cal[hidden] { display: none; }
/* No scrollbars anywhere inside the popup — it is a small surface and the
   columns are short enough to read as scrollable from their content alone.
   All three properties are needed: Firefox reads scrollbar-width, WebKit and
   Chromium the pseudo-element, old Edge the -ms property. */
.dp-cal, .dp-cal * { scrollbar-width: none; -ms-overflow-style: none; }
.dp-cal::-webkit-scrollbar,
.dp-cal *::-webkit-scrollbar { width: 0; height: 0; display: none; }
/* The hidden ATTRIBUTE loses to any author display: rule — [hidden]{display:none}
   lives in the UA sheet, and an author sheet beats it at any specificity. Without
   this blanket, .dp-cal-time{display:flex} would keep the time column on screen
   for a date-only field and it would read as "the JS never ran". A blanket over
   the subtree covers the parts nobody has written yet. */
.dp-cal [hidden] { display: none !important; }

/* ── the brand panel ─────────────────────────────────────────────────────── */
.dp-cal-side {
  flex: 0 0 150px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--dp-brand);
  color: var(--FontColor, #fff);
  text-align: center;
  cursor: grab;                  /* the whole bar is the drag handle */
  touch-action: none;
}
.dp-cal-side:active { cursor: grabbing; }
/* Click to copy. The cursor stays `grab` on the bar itself because the bar is
   also the drag handle; these are the parts that copy. */
.dp-cal-dow, .dp-cal-copy { cursor: copy; }
.dp-cal-dow {
  background: var(--dp-brand-d);
  color: var(--FontColor, #fff);
  font-size: 1.05rem;
  font-weight: 700;
  padding: 1.05rem 1.1rem;
}
/* The day number and the month are one block, centered together, with the year
   held at the foot — the reference's layout. The year is out of flow so the
   pair stays optically centered whatever the month name's length. */
.dp-cal-body {
  flex: 1 1 auto;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.1rem;
}
/* The selected time, under the weekday strip and on the lighter brand field. */
.dp-cal-timeread {
  padding: .7rem 1.1rem 0;
  font-size: 1.35rem;
  font-weight: 400;
  opacity: .92;
}
.dp-cal-dnum { font-size: 4.2rem; font-weight: 300; line-height: 1; opacity: .92; }
/* NEVER truncated. September is the longest at 107.0px against a 111.3px content
   box — 4px of slack, which a different root size or font stack eats. Three
   pixels off the type buys ~14px instead, so the name always fits whole. */
.dp-cal-mon  { font-size: 1.18rem; font-weight: 400; line-height: 1.1; opacity: .92; margin: 0;
               white-space: nowrap; }
.dp-cal-yr   { position: absolute; left: 0; right: 0; bottom: 1.1rem;
               font-size: 2.1rem; font-weight: 300; opacity: .92; }

/* ── the calendar ────────────────────────────────────────────────────────── */
/* A DEFINITE width. Left to size itself the panel tracked the nav row, and the
   month names span 26.2px (July) to 83.2px (September) — measured — so the
   window grew and shrank as you paged through the year. */
.dp-cal-main {
  flex: 0 0 20rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: .9rem 1rem 0;
  background: color-mix(in srgb, var(--InputBgColor, #fff), var(--FontColor, #000) 4%);
}
.dp-cal-nav { display: flex; justify-content: space-between; gap: .5rem; margin-bottom: .55rem; }
.dp-cal-navgrp { display: flex; align-items: center; gap: .1rem; }
.dp-cal-arrow {
  width: 1.9rem; height: 1.9rem; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: 50%;
  color: var(--InputPlaceholderColor, rgba(0, 0, 0, .4));
  font-size: 1.1rem; line-height: 1; cursor: pointer;
}
.dp-cal-arrow:hover,
.dp-cal-arrow:focus-visible {
  background: var(--dp-brand);
  color: var(--InputBgColor, #fff);
}
.dp-cal-navlabel {
  min-width: 5.2rem; text-align: center;
  font-size: 1.05rem; font-weight: 500;
  color: var(--FontColor, rgba(0, 0, 0, .7)); opacity: .75;
}
.dp-cal-navgrp + .dp-cal-navgrp .dp-cal-navlabel { min-width: 3.4rem; }

.dp-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.dp-cal-dowh {
  text-align: center; padding: .3rem 0 .45rem;
  font-size: .82rem; font-weight: 700;
  color: var(--color1, #0079C1);
}
.dp-cal-day {
  aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
  padding: 0; border: 0; border-radius: 6px;
  background: none; color: var(--FontColor, rgba(0, 0, 0, .85));
  font-size: .95rem; line-height: 1; cursor: pointer;
}
/* Adjacent-month days stay readable but quieter — opacity, not a lighter
   ink. A lighter ink on the brand fill (when the cell is also .is-sel) is
   what made the digit disappear: measured 2026-09-16 09:10 MDT, the "6"
   inside the chip was brand-tint blue on brand blue, zero white pixels. */
.dp-cal-day.is-out { opacity: .6; }
.dp-cal-day:hover  { background: var(--dp-brand-xl); }
.dp-cal-day.is-today { box-shadow: inset 0 0 0 1px var(--color1xl, #66b0da); }
/* Selected is the brand fill, not the reference's neutral chip — "using built
   in colors" is the instruction, and a gray chip is that library's default
   rather than a token. Flip to neutral by overriding this one rule.
   color is literal #fff, not var(--InputBgColor): an empty InputBgColor makes
   the declaration invalid and the .is-out ink wins, which is the invisible
   digit. opacity:1 beats .is-out's .6 so the reversed digit is full strength. */
.dp-cal-day.is-sel {
  background: var(--color1, #0079C1);
  color: #fff;
  font-weight: 600;
  opacity: 1;
}
.dp-cal-day.is-out.is-sel {
  color: #fff;
  opacity: 1;
}

.dp-cal-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; padding: .7rem 0 .8rem;
}
.dp-cal-foot-r { display: flex; gap: .35rem; }
.dp-cal-act {
  background: none; border: 0; border-radius: 4px;
  padding: .45rem .7rem;
  font-size: .92rem; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color1, #0079C1); cursor: pointer;
}
.dp-cal-act:hover,
.dp-cal-act:focus-visible {
  background: var(--dp-brand);
  color: var(--InputBgColor, #fff);
}
/* The reference paints Clear red. There is no red in the token set — measured,
   --RequiredColor is rgba(0,0,0,.5) on TurnerLee — so it reads as the muted
   secondary action rather than a hardcoded hex. */
.dp-cal-act-clear { color: var(--InputPlaceholderColor, rgba(0, 0, 0, .45)); }
.dp-cal-act-clear:hover,
.dp-cal-act-clear:focus-visible { color: var(--InputBgColor, #fff); }

/* ── the time column, only for datetime-local ────────────────────────────── */
/* The columns are taken OUT OF FLOW so 60 minutes cannot set the popup's height.
   In flow they did exactly that — measured 2026-09-16 08:10 MDT, the datetime
   popup grew to the full minute list and ran off the screen. Out of flow the
   time block contributes no intrinsic height, so the calendar sets it and the
   columns scroll inside whatever is left. */
.dp-cal-time {
  flex: 0 0 auto;
  align-self: stretch;         /* full height of the popup, same as the calendar */
  position: relative;
  width: 6rem;                 /* two 3rem columns */
  border-left: 1px solid var(--InputBorderColor, rgba(0, 0, 0, .12));
  /* Calendar (.dp-cal-main) keeps the 4% ink wash; this panel is pure InputBg
     so the time group reads as its own zone. PM hours still carry --dp-brand-f1
     on .dp-cal-topt.is-pm — that wash sits on top of this white. */
  background: var(--InputBgColor, #fff);
}
.dp-cal-time-h {
  padding: .85rem 0 .5rem; text-align: center;
  font-size: .82rem; font-weight: 700;
  color: var(--color1, #0079C1);
}
.dp-cal-time-cols {
  position: absolute; top: 2.4rem; left: 0; right: 0; bottom: 0;
  display: flex;
}
.dp-cal-tcol {
  flex: 1 1 0; min-width: 0; margin: 0; padding: 0 0 .8rem; list-style: none;
  overflow-y: auto;
  overscroll-behavior: contain;      /* belt; the wheel handler is the braces —
                                        overscroll-behavior is read when the
                                        GESTURE STARTS, so it cannot be relied on
                                        alone to stop a scroll already in flight */
  scroll-behavior: auto;                    /* a test has to be able to jump it */
}
.dp-cal-tcol + .dp-cal-tcol { border-left: 1px solid var(--InputBorderColor, rgba(0, 0, 0, .07)); }
.dp-cal-topt {
  display: block; width: 100%; padding: .32rem 0;
  background: none; border: 0; border-radius: 4px;
  font-size: .92rem; text-align: center; cursor: pointer;
  color: var(--FontColor, rgba(0, 0, 0, .85));
}
/* PM carries a soft --color1f1 wash so a 12-hour list is still unambiguous.
   The button's data value stays 0-23, so nothing downstream changes. */
.dp-cal-topt.is-pm { background: var(--dp-brand-f1); }
.dp-cal-topt:hover { background: var(--dp-brand-xl); }
.dp-cal-topt.is-sel { background: var(--color1, #0079C1); color: var(--InputBgColor, #fff); font-weight: 600; }

/* WEBKIT UNDER-SIZES THE ROW, v1.025. Craig 2026-09-25: "i can't enter time
   because it's cut off on right edge ... make sure on all browsers that all time
   slots on the right edge are in full view." Measured on turnerlee.com/ops/schedule
   at 661-1600 wide: Chromium sizes .dp-cal to 608px (150 + 20rem + 6rem at a 17.6px
   root), WebKit to 569px — it sums the time panel's CONTENT (its columns are out of
   flow, so only the "Time" header counts) instead of its 6rem width, and
   overflow:hidden then cut 39px off the minutes. A min-width floor is part of every
   engine's max-content contribution, so each panel now brings its full width. Wide
   layout only: under 661px the panels stack and must be free to shrink. */
@media (min-width: 661px) {
  .dp-cal-side { min-width: 150px; }
  .dp-cal-main { min-width: 20rem; }
  .dp-cal-time { min-width: 6rem; }
}

/* ── narrow: the brand panel becomes a header so the popup still fits ─────── */
@media (max-width: 660px) {
  /* Stacked, the day cells are aspect-ratio 1/1 across the full width, which at
     613px made the popup 913px tall — taller than the window. Cap the calendar's
     own measure and let the box scroll as a last resort. */
  .dp-cal {
    flex-wrap: wrap; width: auto;
    max-width: calc(100vw - 1.5rem);
    max-height: calc(100vh - 1rem);
    overflow-y: auto;
  }
  /* width + align-self, NOT auto margins: an auto cross-axis margin turns off
     the flex item's stretch, so the grid collapsed to its min-content and the
     day cells came out ~25px with the selected chip clipping its own number. */
  .dp-cal-nav, .dp-cal-grid, .dp-cal-foot { width: 100%; max-width: 20rem; align-self: center; }
  /* THE HEADER IS TWO LINES, NOT ONE.
     Weekday and time are context; the date is the answer. On one baseline row
     all five sat at near-identical sizes with 9.7 / 9.7 / 8.8 / 8.8px between
     them — one spacing value repeated until nothing reads as primary — and at
     320 the row ran off the edge with "2026" clipped and the time splitting
     after "9:30". Grid areas give the two lines without touching the DOM.
     Rhythm is deliberate: 0.4rem inside the date phrase, 0.55rem inside the
     meta pair, 0.35rem between the two levels, 0.9-1rem framing the panel. */
  /* Wrap, do not grid: `flex-basis:100%` on the date puts it on its own line and
     lets the weekday + time pair wrap as a centered GROUP above it. A two-track
     grid cannot center that pair — the tracks are sized by the wider date row
     spanning them, so the column boundary lands wherever that row decides. */
  .dp-cal-side {
    flex: 1 1 100%;
    display: flex;
    flex-direction: row;          /* the base rule is column; wrapping a column
                                     puts every item on its own line and centers
                                     on the wrong axis */
    flex-wrap: wrap;
    justify-content: center;
    align-items: baseline;
    column-gap: .55rem;
    row-gap: .35rem;
    padding: .9rem 1rem 1rem;
    text-align: center;
  }
  .dp-cal-dow { flex: 0 0 auto; background: none; padding: 0; font-size: .92rem; }
  .dp-cal-timeread { flex: 0 0 auto; padding: 0; font-size: .92rem; white-space: nowrap; }
  .dp-cal-body {
    flex: 0 0 100%;
    position: static;                 /* the year leaves the corner it is pinned to when wide */
    flex-direction: row; justify-content: center; align-items: baseline;
    gap: .35rem; padding: 0;
  }
  /* Reads as one sentence — "September 16, 2026" — so the day sits between the
     month and the year at the same size. `order` reflows it without touching the
     DOM, which keeps the copy targets and the reading order they are bound to.
     The comma is generated content, so textContent, and therefore what a click
     copies, is unchanged. */
  .dp-cal-mon  { order: 1; }
  .dp-cal-dnum { order: 2; font-size: 1.15rem; font-weight: 400; }
  .dp-cal-dnum::after { content: ','; }
  .dp-cal-yr   { order: 3; position: static; }
  .dp-cal-mon, .dp-cal-yr { font-size: 1.15rem; white-space: nowrap; }
  .dp-cal-main { flex: 1 1 100%; }
  .dp-cal-time { flex: 1 1 100%; width: auto; position: static;
                 border-left: 0; border-top: 1px solid var(--InputBorderColor, rgba(0, 0, 0, .12)); }
  .dp-cal-time-cols { position: static; justify-content: center; }
  .dp-cal-tcol { flex: 0 0 3rem; max-height: 9rem; }
}
