/* --lg-blur has to be REGISTERED or it cannot carry a transition: an
   unregistered custom property has no animation type in Chromium, so the
   delay that keeps the panel unblurred while it scales is silently dropped
   and the value flips the instant .is-open lands. liquid-glass.css declares
   --lg-blur on [data-glass] and every .lg-surface INHERITS it, so
   inherits:true keeps that chain intact; initial-value 14px reproduces the
   var(--lg-blur,14px) fallback that liquid-glass.js writes inline, which is
   the only value elements outside [data-glass] ever saw. Registering is
   therefore behaviour-neutral for the rest of the site. */
@property --lg-blur{ syntax:'<length>'; inherits:true; initial-value:14px; }

/* ky-cal2 — the booking instrument. Styles the DOM built by ky/ky-cal2.js and
   SUPERSEDES ky/ky-cal.css (drop that <link>; every rule it owned is either
   ported here or deliberately replaced).

   THE TWO SURFACES
   ----------------
   1. #ky-cal        the in-flow hero preview. NO backdrop-filter and NO lens
                     of its own: it lives inside the portfolio's scroller and
                     the liquid-glass PERF LAW says only fixed chrome may be
                     lensed. Whether it paints as glass or as bare numerals is
                     not decided here — ky-glassify tags it .ky-glass and
                     ky/ky-mode.css's duality law decides which of the two it
                     means. This file only shapes it.
   2. #ky-cal-panel  the instrument. position:fixed, carrying .lg-surface, so
                     ky/liquid-glass.js lenses it with exactly the same
                     material as the music bar.

   THE MATERIAL IS NOT RE-DECLARED HERE. v1's stylesheet carried its own copy
   of the frost recipe at ID specificity, which meant retuning the glass lane
   changed every surface on the site EXCEPT the calendar. This file declares no
   background on the panel in wallpaper mode at all: liquid-glass.css owns the
   pane, ky-mode.css owns the ink plate, and the only things turned here are
   the material's own documented inputs (--kyg-alpha, --lg-surface,
   --lg-bright / --lg-contrast) — and only on a dark plate, where they have to
   move (see DARK PLATES below).

   NO BACKDROP-FILTER ANYWHERE IN THIS FILE except on the scrim, which is
   fixed. Everything inside the panel is a wash of the panel's OWN ink over the
   panel's own plate — the panel scrolls its content, and a filtered element
   inside a scroller re-runs its filter chain every frame.

   THE COLOUR CONTRACT — why this file has no hex codes in its meaning-bearing
   rules. ky/ky-wave.js flips chrome by stamping the site's 14 --color-*
   properties INLINE on each registered element as the wavefront reaches it,
   then clearing them at commit once the root holds byte-identical values. A
   surface that hardcodes its colours is simply skipped by that flip. So every
   ground, rule, mark and label below resolves from:

     --kyc-ink    --color-foreground      the ink pole (LIFTS TO CREAM on dark
                                          plates — that is the site's rule, not
                                          a bug: see DARK PLATES)
     --kyc-glow   --color-accent-200      the LIVE plate accent. Honey on the
                                          base theme, violet on singularity,
                                          rain-blue on courtyard-rain. Carries
                                          personality, never meaning.
     --kyc-mark   --color-accent-600      the side accent. Carries MEANING
                                          (strikes, dots, heat) because it holds
                                          its weight against both poles.
     --kyc-btn / --kyc-btnt
                  --color-secondary-300 / --ky-btntext
                                          the site's own button pair, which is
                                          already correct at both poles — which
                                          is exactly why the pill and the
                                          primary action use it instead of
                                          inverting ink by hand.

   STATE IS CARRIED BY SHAPE, NEVER BY COLOUR ALONE. Every day state has an
   inked glyph: a strike for booked, a hairline slash for closed, a half-filled
   disc for a part day, a corner tick for a day that carries a note. That is
   both the accessibility floor and the reason the grid still reads on a
   violet plate, on a blue plate, and in monochrome.

   DARK PLATES. ky-wave lifts the ink pole to cream when a wallpaper's manifest
   luma is under 25 — so on those plates --color-foreground is cream and
   --color-background is STILL a light cream tint. A pane tinted with
   --color-background would then be cream type on a cream pane. ky-cal2.js
   publishes data-kyc-dark="1" (read from ky:wall-theme's detail.dark and from
   __kyWave.isDark) precisely because that condition cannot be derived from a
   custom property in CSS, and the [data-kyc-dark="1"] blocks below tint the
   pane the other way. They are the ONLY place in this file that names a
   literal pole: on a dark plate every ink token has already lifted, so there
   is no token left that names the dark one. #14110A and #F7EDD3 are the house
   ink and cream constants — the same literals ky-wave.js carries as BASE.main
   and BASE.surface. (The #ky-sw dev row and the contact-band field at the foot
   of this file are the other two exemptions, and for the same reason: neither
   sits on a themed surface. Both are ported unchanged from v1.)

   SLIDE.HTML. That page owns its own hero preview: an inline controller
   re-renders #ky-cal's children in the kyc2-* vocabulary and its stylesheet
   hand-tunes the result. So section 1's BASE rules are v1's, unchanged in
   shape and specificity, and every enrichment is scoped
   html:not([data-ky-slide]) so slide keeps exactly the calendar the owner
   tuned. #ky-cal's own ::before / ::after are left FREE throughout — ky/
   ky-wallfx.css puts the per-plate frost sheen and ember rim there.          */

:root{
  --kyc-ease:     cubic-bezier(.51,.92,.24,1.15);   /* house overshoot */
  --kyc-ease-out: cubic-bezier(.22,1,.36,1);        /* house expo-out  */
}

/* ═══════════════════════════════════════════════════════════════════════════
   1. HERO PREVIEW  (#ky-cal)
   ═══════════════════════════════════════════════════════════════════════════ */

#ky-cal{
  /* button reset — the whole grid is ONE control that opens the instrument */
  -webkit-appearance:none; appearance:none;
  margin:.2em 0 0; padding:.35em .5em .45em; border:0;
  background:transparent; color:inherit; font:inherit; text-align:inherit;
  cursor:pointer; -webkit-tap-highlight-color:transparent;

  display:inline-grid;
  grid-template-columns:repeat(7,2.4ch);
  gap:.55em .55ch;
  justify-items:center;
  font-family:inherit;
  font-size:1.14em;
  line-height:1;
  border-radius:14px;
  /* NOT transform: ky/ky-wallfx.js springs this element every frame through
     --kyfx-x / --kyfx-y / --kyfx-s and a transition here would fight it. */
  transition:background-color .28s var(--kyc-ease-out),
             box-shadow .28s var(--kyc-ease-out);
}
#ky-cal:hover,
#ky-cal:focus-visible{
  background:color-mix(in srgb, var(--color-foreground,#14110A) 7%, transparent);
}
#ky-cal:focus-visible{
  outline:2px solid var(--color-foreground,#14110A);
  outline-offset:3px;
}

#ky-cal .kyc2-mo{
  grid-column:1/-1; justify-self:end;
  letter-spacing:.14em; opacity:.85; padding-bottom:.15em;
  display:flex; align-items:center; gap:.6ch;
}
#ky-cal .kyc2-mo::after{
  content:"\2192";                 /* the site's own trailing-arrow glyph */
  opacity:.55;
  transition:transform .3s var(--kyc-ease), opacity .3s var(--kyc-ease-out);
}
#ky-cal:hover .kyc2-mo::after,
#ky-cal:focus-visible .kyc2-mo::after{ transform:translateX(3px); opacity:1; }

#ky-cal .kyc2-w{ opacity:.45; font-size:.7em; align-self:center; }
#ky-cal .kyc2-o{ opacity:0; }
#ky-cal .kyc2-d{
  position:relative; opacity:.8;
  width:2.4ch; height:2.4ch;
  display:flex; align-items:center; justify-content:center;
}

/* today — the filled ink pill that shipped here */
#ky-cal .kyc2-d.is-today{
  background:var(--color-secondary-300, var(--color-foreground,#14110A));
  color:var(--ky-btntext, var(--color-accent-200,#E3AC33));
  border-radius:999px;
  opacity:1;
}

/* BUSY — never colour alone. Ink drops to a muted weight AND a strike rule in
   the theme's side colour crosses the numeral. .72 is the floor that still
   clears 4.5:1 against the honey ground while reading as recessed next to the
   .8 of an open day; the strike does the rest of the work. */
#ky-cal .kyc2-d.is-busy{ opacity:.72; }
#ky-cal .kyc2-d.is-busy::after{
  content:""; position:absolute; left:8%; right:8%; top:50%;
  height:1.5px; transform:translateY(-50%) rotate(-24deg);
  background:var(--color-accent-600,#C4901D);
  border-radius:2px;
}
/* HALF — a dot under the numeral, distinct in SHAPE from the strike */
#ky-cal .kyc2-d.is-half::after{
  content:""; position:absolute; left:50%; bottom:-.28em;
  width:3px; height:3px; margin-left:-1.5px; border-radius:999px;
  background:var(--color-accent-600,#C4901D);
}

/* ── the two enrichments (index only) ───────────────────────────────────────
   A month load bar and its count, both aria-hidden — the button's accessible
   name already says "N days open". Skipped entirely on slide.html by the JS,
   and scoped out of it here as well so a cached build cannot leak them in. */
html:not([data-ky-slide]) #ky-cal .kyc2-meter{
  grid-column:1/-1; justify-self:stretch;
  height:2px; margin-top:.55em; border-radius:2px;
  background:color-mix(in srgb, var(--color-foreground,#14110A) 14%, transparent);
  overflow:hidden;
}
html:not([data-ky-slide]) #ky-cal .kyc2-meter i{
  display:block; height:100%; border-radius:2px;
  background:var(--color-accent-600,#C4901D);
  transition:width .5s var(--kyc-ease-out);
}
html:not([data-ky-slide]) #ky-cal .kyc2-cap{
  grid-column:1/-1; justify-self:end;
  margin-top:.35em;
  font-size:.56em; letter-spacing:.16em; text-transform:uppercase;
  opacity:.62;
}

/* on a dark plate the in-flow pane has to smoke instead of cream, for the same
   reason the panel does (see the DARK PLATES note in the header). Scoped away
   from slide.html, which tunes its own preview by eye. */
html.ky-wallmode:not([data-ky-slide]) #ky-cal[data-kyc-dark="1"]{
  --kyg-surface: color-mix(in srgb, #14110A 72%, var(--color-accent-200,#E3AC33));
  --kyg-tint: 44%;
  --lg-bright: .70;
  --lg-contrast: .84;
}

/* ═══════════════════════════════════════════════════════════════════════════
   2. THE SCRIM
   A shade, not a pane: enough to catch the click-outside and to settle the
   page back, never a blackout. (v1 shipped 62% ink here, which is precisely
   what made the panel read as "another calendar on my main screen".)
   ky-mode.css strips the blur in ink mode and keeps the wash.
   ═══════════════════════════════════════════════════════════════════════════ */
#ky-cal-scrim{
  position:fixed; inset:0; z-index:9400;
  background:color-mix(in srgb, var(--color-foreground,#14110A) 15%, transparent);
  backdrop-filter:blur(2px);
  -webkit-backdrop-filter:blur(2px);
  opacity:0; pointer-events:none;
  transition:opacity .34s var(--kyc-ease-out);
}
#ky-cal-scrim.is-open{ opacity:1; pointer-events:auto; }
/* on a dark plate the ink pole is cream, so an "ink" wash would BRIGHTEN the
   page behind the panel. The shade is floored at the house ink constant. */
html.ky-wallmode #ky-cal-scrim[data-kyc-dark="1"]{
  background:color-mix(in srgb, #14110A 30%, transparent);
}

/* ═══════════════════════════════════════════════════════════════════════════
   3. THE PANEL SHELL + THE TWO SKINS
   ═══════════════════════════════════════════════════════════════════════════ */
#ky-cal-panel{
  /* ---- the colour contract (see the file header) ---- */
  --kyc-ink:   var(--color-foreground, #14110A);
  --kyc-glow:  var(--color-accent-200, #E3AC33);
  --kyc-mark:  var(--color-accent-600, #C4901D);
  --kyc-btn:   var(--color-secondary-300, #14110A);
  --kyc-btnt:  var(--ky-btntext, #E3AC33);

  /* ---- geometry ----
     44px is the touch-target floor and also what keeps a cell close to square
     once the 7 columns have shared out what the rail leaves them (measured at
     the 724px panel: 53 x 44). The pill is sized from the cell's real box, so
     the two can never disagree. */
  --kyc-r:    24px;
  --kyc-cell: 44px;
  --kyc-gap:  4px;
  --kyc-wk:   26px;
  --kyc-rail: 15.5rem;

  /* The glass opacity knob ky/ky-mode.css section (2a) feeds into BOTH glass
     recipes. Raised from the material's 14% default because this surface
     carries body copy, a data grid and controls: its legibility must not
     depend on what happens to be scrolled behind it. Declaring it costs
     nothing in ink mode, where ky-mode.css forces an opaque plate anyway. */
  --kyg-alpha: 30%;

  position:fixed; z-index:9500;
  left:var(--kyc-x, 50%);
  top:var(--kyc-y, 50%);
  width:min(724px, 100vw - 24px);
  max-height:min(768px, 100svh - 24px);
  overflow:auto; overscroll-behavior:contain;
  display:flex; flex-direction:column;
  padding:15px 15px 13px;
  border-radius:var(--kyc-r);
  isolation:isolate;

  font-family:montrealMono,'montrealMono Fallback','Space Mono',
              ui-monospace,SFMono-Regular,Menlo,monospace;
  color:var(--kyc-ink);
  font-size:13px;
  font-variant-numeric:tabular-nums;

  /* ── ANCHORED TO THE HERO WIDGET ────────────────────────────────────────
     v1 was `top:50% left:50%` + translate(-50%,-50%): a second calendar
     arriving in the middle of the screen, which is what the owner objected
     to. ky-cal2.js measures the hero preview and writes --kyc-x/--kyc-y
     (where the panel sits) and --kyc-ox/--kyc-oy (where inside itself it
     grows FROM), so the instrument scales out of the widget that was
     clicked. The fallbacks keep the centred behaviour if the JS never runs. */
  transform-origin:var(--kyc-ox, 50%) var(--kyc-oy, 50%);
  transform:scale(.9);
  opacity:0; visibility:hidden;

  /* ── DO NOT BLUR WHILE MOVING ───────────────────────────────────────────
     MEASURED (4x CPU throttle, 3 open/close cycles, rAF sampler that only
     OBSERVES — never scrolls or reads layout):

       shipped                    open p50 144.4ms   close p50 166.6ms
       panel backdrop-filter off  open p50 100.0ms   close p50 105.5ms
       cell stagger off           open p50 155.6ms   close p50 205.5ms   (none)
       all backdrop-filter off    open p50  77.8ms   close p50  77.8ms

     The 42-cell stagger is INNOCENT — removing it changes nothing. The whole
     cost is the backdrop: a backdrop-filtered surface that is also being
     SCALED has to re-sample and re-blur everything behind it at a new
     geometry on every single frame, and this panel scales .9 -> 1 over 460ms
     across a live video wallpaper. That is the hiccup the owner saw.

     The fix keeps the glass and refuses to animate it: the blur is held at 0
     for as long as the transform is moving, then snaps in once the panel is
     standing still. The panel arrives, THEN focuses. Cheap frames while
     anything moves; the full material at rest, which is the only time anyone
     reads it.

     THE LEVER IS --lg-blur, NOT backdrop-filter. Writing backdrop-filter here
     is INERT, and that was measured: liquid-glass.js puts an INLINE filter on
     every .lg-surface, and an inline style beats any stylesheet rule. But it
     builds that filter out of CUSTOM PROPERTIES, and a custom property inside
     an inline value resolves against the element the inline style sits on, so
     re-declaring --lg-blur on this panel retargets the inline filter with no
     important flag and no specificity war.

     It is a KEYFRAME, not a transition, and that distinction was also
     measured. ky-cal2.js inserts the panel already carrying .is-open, so
     there is no previous computed style for a transition to start from and
     the delayed flip was silently dropped every time. An animation runs on a
     freshly inserted element regardless. The property still has to be
     registered to animate at all (see the @property at the top of this file).
     0% to 91% holds 0px across the whole 460ms transform; the last step snaps
     to full. Closing needs no animation: the base rule below is 0px, so the
     shrink is cheap the instant .is-open leaves. */
  --lg-blur:0px;
  transition:opacity .28s var(--kyc-ease-out),
             transform .44s var(--kyc-ease),
             visibility 0s linear .44s;
}
@keyframes kyc-panel-focus{
  0%,91%{ --lg-blur:0px; }
  100%  { --lg-blur:30px; }
}
#ky-cal-panel.is-open{
  opacity:1; visibility:visible;
  transform:scale(1);
  animation:kyc-panel-focus .5s linear both;
  transition:opacity .24s var(--kyc-ease-out),
             transform .46s var(--kyc-ease),
             visibility 0s;
}
/* the scrim's own blur is a plain stylesheet rule (it is not an .lg-surface),
   so it takes the same treatment directly: nothing blurs while the opacity
   fade is running. */
#ky-cal-scrim{
  backdrop-filter:blur(0px);
  -webkit-backdrop-filter:blur(0px);
}
#ky-cal-scrim.is-open{
  backdrop-filter:blur(2px);
  -webkit-backdrop-filter:blur(2px);
  transition:opacity .34s var(--kyc-ease-out),
             backdrop-filter 1ms linear .36s,
             -webkit-backdrop-filter 1ms linear .36s;
}
/* the widget is off screen (deep-linked, or the hero scrolled past): the
   centred presentation is the only sensible place left */
#ky-cal-panel.is-centred{
  left:50%; top:50%;
  transform-origin:50% 50%;
  transform:translate(-50%,-50%) scale(.965);
}
#ky-cal-panel.is-centred.is-open{ transform:translate(-50%,-50%) scale(1); }
#ky-cal-panel *{ box-sizing:border-box; }

/* the stepped inner hairline — the music bar's continuous-curvature read */
#ky-cal-panel::before{
  content:""; position:absolute; inset:1px; z-index:3; pointer-events:none;
  border-radius:calc(var(--kyc-r) - 1.5px);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--kyc-ink) 10%, transparent);
}
/* liquid-glass.js parks its specular span at z-index 2; the instrument's own
   sections have to sit above it or the conic highlight crosses the grid */
#ky-cal-panel > *:not(.lg2-spec){ position:relative; z-index:4; }

/* ── SKIN A · WALLPAPER MODE = GLASS ──────────────────────────────────────
   Nothing is painted here. .lg-surface (ky/liquid-glass.css) is the pane,
   ky-mode.css (2a)/(2b) route --kyg-alpha and the accent through it, and
   liquid-glass.js lenses it because it is fixed. The ONLY intervention is on
   dark plates, where the ink pole has lifted to cream and the pane therefore
   has to tint toward ink instead of toward paper. */
html.ky-wallmode #ky-cal-panel[data-kyc-dark="1"]{
  --lg-surface: color-mix(in srgb, #14110A 74%, var(--color-accent-200,#E3AC33));
  --kyg-alpha: 48%;
  --lg-bright: .66;
  --lg-contrast: .82;
  --lg-sheen: 12%;
  border-color:color-mix(in srgb, #F7EDD3 22%, transparent);
}
/* the glass gate is missing entirely (ky-glassify blocked or errored): a bare
   .lg-surface has NO background, and a transparent panel of text over the page
   is the one failure this file must not allow. Scoped to :not([data-glass]) so
   it can never out-rank the real material. */
html:not([data-glass]) #ky-cal-panel{
  background:var(--color-background, #F7EDD3);
  border:1px solid color-mix(in srgb, var(--kyc-ink) 80%, transparent);
  box-shadow:6px 8px 0 -5px color-mix(in srgb, var(--kyc-ink) 16%, transparent);
}

/* ── SKIN B · HONEY & INK = PURE INK ──────────────────────────────────────
   ky/ky-mode.css (1e) already turns the panel itself into an opaque
   --color-background print plate with an ink border and a hard-offset print
   shadow, at (1,2,1). This block does the other half: everything INSIDE the
   panel that leans on translucency in wallpaper mode goes to a flat ink wash
   on that plate, and no blur survives anywhere. Geometry is untouched — the
   strip is paint-only, exactly as the duality law requires. */
html:not(.ky-wallmode) #ky-cal-panel,
html:not(.ky-wallmode) #ky-cal-panel *{
  backdrop-filter:none !important;
  -webkit-backdrop-filter:none !important;
}
html:not(.ky-wallmode) #ky-cal-panel .kyc3-rail,
html:not(.ky-wallmode) #ky-cal-panel .kyc3-sum{
  background:color-mix(in srgb, var(--kyc-ink) 6%, var(--color-background,#F7EDD3));
  border-color:color-mix(in srgb, var(--kyc-ink) 26%, transparent);
}
/* the print-register rule: in ink mode the sections are divided by a real
   drawn line rather than by a light seam */
html:not(.ky-wallmode) #ky-cal-panel .kyc3-mast,
html:not(.ky-wallmode) #ky-cal-panel .kyc3-scrub,
html:not(.ky-wallmode) #ky-cal-panel .kyc3-foot{
  border-color:color-mix(in srgb, var(--kyc-ink) 30%, transparent);
}

/* ═══════════════════════════════════════════════════════════════════════════
   4. MASTHEAD
   ═══════════════════════════════════════════════════════════════════════════ */
#ky-cal-panel .kyc3-mast{
  display:flex; align-items:flex-start; gap:10px;
  padding-bottom:11px; margin-bottom:11px;
  border-bottom:1px solid color-mix(in srgb, var(--kyc-ink) 16%, transparent);
}
#ky-cal-panel .kyc3-mast-w{ min-width:0; }
/* This is an <h2>, and html.honeykit puts filter:url(#roughen) on every h2 —
   the site's own signature. At 15px that read as damage rather than as
   texture (screenshot-verified in v1), so the title is sized up to carry it
   and the small-caps sub-label is a SIBLING, outside the filtered element. */
#ky-cal-panel .kyc3-title{
  font-size:var(--text-heading-3, 22px); font-weight:600; letter-spacing:-.015em;
  line-height:1.02; margin:0;
}
#ky-cal-panel .kyc3-sub{
  display:flex; align-items:center; gap:6px; margin-top:6px;
  font-size:10px; letter-spacing:.16em; text-transform:uppercase;
  opacity:.66; font-weight:400; filter:none;
}
#ky-cal-panel .kyc3-dot{
  width:5px; height:5px; border-radius:999px; flex:0 0 5px;
  background:var(--kyc-mark);
}
#ky-cal-panel .kyc3-x{
  margin-left:auto; flex:0 0 auto;
  width:44px; height:44px; border-radius:999px; border:0; padding:0;
  display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--kyc-ink) 9%, transparent);
  color:var(--kyc-ink); cursor:pointer; font:inherit; font-size:14px;
  transition:background-color .22s var(--kyc-ease-out),
             transform .24s var(--kyc-ease);
}
#ky-cal-panel .kyc3-x:hover{
  background:color-mix(in srgb, var(--kyc-ink) 20%, transparent);
  transform:scale(1.07);
}
#ky-cal-panel .kyc3-x:active{ transform:scale(.94); }

/* ═══════════════════════════════════════════════════════════════════════════
   5. THE YEAR TAPE
   Twelve months of horizon, each pip carrying its own open-days heat, with the
   booking horizon drawn as a hard edge rather than discovered by clicking.
   The year labels are a second grid on the same twelve columns, each label
   spanning its own run of months — so a year boundary is a visible seam.
   ═══════════════════════════════════════════════════════════════════════════ */
#ky-cal-panel .kyc3-tape{
  display:grid; gap:4px; margin-bottom:11px;
}
#ky-cal-panel .kyc3-tape-years{
  display:grid; grid-template-columns:repeat(12,1fr);
  font-size:9px; letter-spacing:.2em; opacity:.5;
}
#ky-cal-panel .kyc3-tape-years span{
  padding-left:2px;
  border-left:1px solid color-mix(in srgb, var(--kyc-ink) 26%, transparent);
}
#ky-cal-panel .kyc3-tape-pips{
  display:grid; grid-template-columns:repeat(12,1fr); gap:3px;
}
#ky-cal-panel .kyc3-pip{
  position:relative;
  display:flex; flex-direction:column; justify-content:flex-end;
  height:34px; padding:0 0 3px; border:0; margin:0;
  border-radius:6px;
  background:color-mix(in srgb, var(--kyc-ink) 7%, transparent);
  color:var(--kyc-ink); font:inherit; cursor:pointer;
  overflow:hidden;
  -webkit-tap-highlight-color:transparent;
  transition:background-color .2s var(--kyc-ease-out),
             transform .24s var(--kyc-ease), opacity .2s linear;
}
/* the heat: the share of the month that is bookable, drawn from the floor */
#ky-cal-panel .kyc3-pip-bar{
  position:absolute; left:0; right:0; bottom:0;
  height:var(--kyc-h, 0%);
  background:color-mix(in srgb, var(--kyc-mark) 46%, transparent);
  transition:height .45s var(--kyc-ease-out);
  pointer-events:none;
}
#ky-cal-panel .kyc3-pip-l{
  position:relative; z-index:1;
  font-size:8.5px; letter-spacing:.06em; text-transform:uppercase;
  text-align:center; opacity:.8;
}
#ky-cal-panel .kyc3-pip:hover:not(:disabled){
  background:color-mix(in srgb, var(--kyc-ink) 16%, transparent);
  transform:translateY(-2px);
}
#ky-cal-panel .kyc3-pip:active:not(:disabled){ transform:translateY(0) scale(.96); }
#ky-cal-panel .kyc3-pip.is-on{
  background:color-mix(in srgb, var(--kyc-ink) 20%, transparent);
  box-shadow:inset 0 0 0 1.5px var(--kyc-ink);
}
#ky-cal-panel .kyc3-pip.is-on .kyc3-pip-l{ opacity:1; font-weight:700; }
/* beyond the horizon: present, legible, and visibly not on offer */
#ky-cal-panel .kyc3-pip.is-out{
  background:transparent; cursor:not-allowed; opacity:.34;
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--kyc-ink) 22%, transparent);
}
#ky-cal-panel .kyc3-pip:focus-visible{
  outline:2px solid var(--kyc-ink); outline-offset:2px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   6. THE SCRUBBER
   ═══════════════════════════════════════════════════════════════════════════ */
#ky-cal-panel .kyc3-scrub{
  display:flex; align-items:center; gap:8px;
  padding-bottom:11px; margin-bottom:11px;
  border-bottom:1px solid color-mix(in srgb, var(--kyc-ink) 16%, transparent);
}
#ky-cal-panel .kyc3-arrow{
  width:40px; height:40px; flex:0 0 40px;
  border-radius:999px;
  border:1px solid color-mix(in srgb, var(--kyc-ink) 24%, transparent);
  background:transparent; color:var(--kyc-ink); cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  font:inherit; font-size:14px; line-height:1;
  transition:background-color .2s var(--kyc-ease-out),
             color .2s linear, transform .26s var(--kyc-ease), opacity .2s linear;
}
#ky-cal-panel .kyc3-arrow:hover:not(:disabled){
  background:var(--kyc-btn); color:var(--kyc-btnt); transform:scale(1.08);
}
#ky-cal-panel .kyc3-arrow:active:not(:disabled){ transform:scale(.93); }
#ky-cal-panel .kyc3-arrow:disabled{ opacity:.24; cursor:not-allowed; }
#ky-cal-panel .kyc3-scrub-mid{ flex:1 1 auto; min-width:0; text-align:center; }
#ky-cal-panel .kyc3-month{
  font-size:var(--text-base, 15px); font-weight:600;
  letter-spacing:.16em; text-transform:uppercase;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
#ky-cal-panel .kyc3-mrow{
  display:flex; align-items:center; gap:8px; margin-top:5px;
}
#ky-cal-panel .kyc3-meter{
  flex:1 1 auto; height:3px; border-radius:2px; overflow:hidden;
  background:color-mix(in srgb, var(--kyc-ink) 14%, transparent);
}
#ky-cal-panel .kyc3-meter i{
  display:block; height:100%; border-radius:2px;
  background:var(--kyc-mark);
  transition:width .5s var(--kyc-ease-out);
}
#ky-cal-panel .kyc3-mlbl{
  flex:0 0 auto;
  font-size:9.5px; letter-spacing:.12em; text-transform:uppercase; opacity:.66;
}
#ky-cal-panel .kyc3-today{
  flex:0 0 auto; height:40px; padding:0 13px;
  border-radius:999px;
  border:1px solid color-mix(in srgb, var(--kyc-ink) 24%, transparent);
  background:transparent; color:var(--kyc-ink); cursor:pointer;
  font:inherit; font-size:9.5px; letter-spacing:.14em; text-transform:uppercase;
  transition:background-color .2s var(--kyc-ease-out), color .2s linear,
             transform .24s var(--kyc-ease), opacity .2s linear;
}
#ky-cal-panel .kyc3-today:hover:not(:disabled){
  background:var(--kyc-btn); color:var(--kyc-btnt);
}
#ky-cal-panel .kyc3-today:active:not(:disabled){ transform:scale(.95); }
#ky-cal-panel .kyc3-today:disabled{ opacity:.24; cursor:default; }

/* ═══════════════════════════════════════════════════════════════════════════
   7. THE CALENDAR
   ═══════════════════════════════════════════════════════════════════════════ */
#ky-cal-panel .kyc3-body{
  display:grid;
  grid-template-columns:minmax(0,1fr) var(--kyc-rail);
  gap:14px; align-items:start;
}
#ky-cal-panel .kyc3-cal{ min-width:0; }

/* the weekday strip — decoration, not column headers: every cell's accessible
   name already carries its own weekday in full */
#ky-cal-panel .kyc3-wkrow{
  display:grid;
  grid-template-columns:var(--kyc-wk) repeat(7,1fr);
  gap:var(--kyc-gap);
  margin-bottom:5px;
}
#ky-cal-panel .kyc3-wkrow span{
  text-align:center; font-size:9.5px; letter-spacing:.12em;
  text-transform:uppercase; opacity:.5;
}
#ky-cal-panel .kyc3-wkh{ opacity:.34 !important; }

/* fixed six rows, so a 28-day month and a 31-day one are the same height and
   the panel never resizes under the cursor */
#ky-cal-panel .kyc3-vp{
  position:relative;
  height:calc(6 * var(--kyc-cell) + 5 * var(--kyc-gap));
  overflow:hidden;
  border-radius:12px;
}
/* DOM focus lives on the grid (the aria-activedescendant pattern), so the
   visible focus indicator has to be drawn on the ACTIVE CELL, not on this box */
#ky-cal-panel .kyc3-vp:focus{ outline:none; }
#ky-cal-panel .kyc3-vp:focus-visible .kyc3-c.is-pilled{
  outline:2px solid var(--kyc-ink); outline-offset:2px;
}
#ky-cal-panel .kyc3-grid{
  position:absolute; inset:0;
  display:grid;
  grid-auto-rows:var(--kyc-cell);
  gap:var(--kyc-gap);
  will-change:transform, opacity;
  /* will-change makes this a STACKING CONTEXT, so the cells' own z-index is
     scoped inside it and the grid as a whole competes with .kyc3-pill at
     z-index auto — i.e. the pill would paint OVER the numerals and the active
     day would render as a blank disc (screenshot-verified in v1). The grid has
     to out-rank the pill HERE, not inside it. */
  z-index:2;
}
#ky-cal-panel .kyc3-grid.is-out{ pointer-events:none; }
#ky-cal-panel .kyc3-row{
  display:grid;
  grid-template-columns:var(--kyc-wk) repeat(7,1fr);
  gap:var(--kyc-gap);
  /* deliberately NOT positioned: the pill measures cells with offsetLeft /
     offsetTop and a positioned row would become their offsetParent */
}

/* ── the week spine ──────────────────────────────────────────────────────
   ISO week number plus a vertical heat rail = the share of that week which is
   bookable. Read off the row's Wednesday (see the note in ky-cal2.js): our
   rows run Sun–Sat and ISO weeks run Mon–Sun, so a row spans two ISO weeks by
   exactly one day and Wednesday is inside the one that covers six of seven. */
#ky-cal-panel .kyc3-wknum{
  position:relative;
  display:flex; align-items:center; justify-content:flex-start;
  padding-left:2px;
  font-size:9px; letter-spacing:.04em; opacity:.55;
}
#ky-cal-panel .kyc3-wknum b{ font-weight:400; }
#ky-cal-panel .kyc3-heat{
  position:absolute; right:3px; bottom:6px;
  width:2px; height:var(--kyc-h, 0%);
  max-height:calc(100% - 12px);
  border-radius:2px;
  background:var(--kyc-mark);
  transition:height .45s var(--kyc-ease-out);
}
#ky-cal-panel .kyc3-wknum.is-cold{ opacity:.28; }

/* ── the travelling pill — one element, transform-animated between cells ── */
#ky-cal-panel .kyc3-pill{
  position:absolute; top:0; left:0;
  width:var(--kyc-cell); height:var(--kyc-cell);
  border-radius:999px;
  background:var(--kyc-btn);
  pointer-events:none; z-index:1;
  opacity:0; transform:translate3d(0,0,0) scale(.6);
  transition:transform .42s var(--kyc-ease), opacity .26s var(--kyc-ease-out);
}
#ky-cal-panel .kyc3-pill.is-on{ opacity:1; }

/* ── day cells ─────────────────────────────────────────────────────────── */
#ky-cal-panel .kyc3-c{
  position:relative; z-index:2;
  min-height:var(--kyc-cell);
  border:0; padding:0; margin:0;
  /* A BOOKABLE day is the one that gets a chip. Filling the blocked days
     instead (v1's first cut) made the days you cannot have the loudest thing
     on the surface. */
  background:color-mix(in srgb, var(--kyc-ink) 10%, transparent);
  color:var(--kyc-ink);
  font:inherit; font-size:13px;
  border-radius:999px; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  -webkit-tap-highlight-color:transparent;
  transition:background-color .2s var(--kyc-ease-out),
             color .18s linear,
             transform .22s var(--kyc-ease);
}
#ky-cal-panel .kyc3-c .kyc3-n{ position:relative; z-index:2; line-height:1; }
#ky-cal-panel .kyc3-c.kyc3-pad{ visibility:hidden; pointer-events:none; }
#ky-cal-panel .kyc3-c:hover:not(:disabled){
  background:color-mix(in srgb, var(--kyc-ink) 22%, transparent);
  transform:translateY(-1px);
}
#ky-cal-panel .kyc3-c:active:not(:disabled){ transform:translateY(0) scale(.93); }
#ky-cal-panel .kyc3-c:focus-visible{ outline:2px solid var(--kyc-ink); outline-offset:-2px; }
#ky-cal-panel .kyc3-c:disabled{ cursor:not-allowed; }

/* TODAY — a ring, so it stays legible whether or not the pill is on it, and a
   slow breath so the instrument has a pulse. opacity + transform only. */
#ky-cal-panel .kyc3-c.is-today::before{
  content:""; position:absolute; inset:3px; border-radius:999px;
  border:1.5px dashed color-mix(in srgb, var(--kyc-ink) 55%, transparent);
  pointer-events:none;
  animation:kyc3-pulse 2.8s var(--kyc-ease-out) infinite;
}
#ky-cal-panel .kyc3-c.is-pilled.is-today::before{
  border-color:color-mix(in srgb, var(--kyc-btnt) 72%, transparent);
}
@keyframes kyc3-pulse{
  0%, 100%{ opacity:.62; transform:scale(1); }
  50%     { opacity:1;   transform:scale(1.06); }
}

/* ── the inked day glyph ─────────────────────────────────────────────────
   A real child element, not a pseudo: ::before is the today ring and ::after
   is the note tick, and a cell needs all three at once. */
#ky-cal-panel .kyc3-c .kyc3-g{
  position:absolute; left:50%; top:50%;
  transform:translate(-50%,-50%);
  pointer-events:none; z-index:3;
  display:block;
}
/* BOOKED — a strike across the numeral. Shape first, colour second. */
#ky-cal-panel .kyc3-c.is-busy{
  background:color-mix(in srgb, var(--kyc-mark) 22%, transparent);
}
#ky-cal-panel .kyc3-c.is-busy .kyc3-g{
  width:58%; height:1.5px; border-radius:2px;
  transform:translate(-50%,-50%) rotate(-24deg);
  background:var(--kyc-mark);
}
/* CLOSED (past / weekend / lead time / beyond horizon) — no chip and a
   hairline slash. MEASURED in v1: washing the numeral out to 62% ink read at
   2.6:1 on the honey ground. Recession is carried by the ABSENCE of the chip
   and by the mark, never by draining the type. */
#ky-cal-panel .kyc3-c.is-blocked{ background:transparent; }
#ky-cal-panel .kyc3-c.is-blocked .kyc3-g{
  width:42%; height:1px; border-radius:1px;
  transform:translate(-50%,-50%) rotate(-24deg);
  background:color-mix(in srgb, var(--kyc-ink) 62%, transparent);
}
/* PART DAY — a half-filled disc under the numeral. Distinct in SHAPE from
   both the strike and the full chip: the day is half on offer, and the mark
   says so literally. */
#ky-cal-panel .kyc3-c.is-half .kyc3-g{
  left:50%; top:auto; bottom:5px;
  transform:translate(-50%,0);
  width:7px; height:7px; border-radius:999px;
  border:1px solid var(--kyc-mark);
  background:linear-gradient(90deg,
    var(--kyc-mark) 0 50%, transparent 50% 100%);
}
/* A DAY THAT CARRIES A NOTE — a corner tick, so "there is something to read
   here" is visible before you land on it. */
#ky-cal-panel .kyc3-c.has-note::after{
  content:""; position:absolute; top:5px; right:7px;
  width:3px; height:3px; border-radius:999px;
  background:var(--kyc-glow);
  box-shadow:0 0 0 1px color-mix(in srgb, var(--kyc-ink) 22%, transparent);
  pointer-events:none;
}
/* THE ACTIVE CELL reads inverted. This MUST come after .is-busy / .is-blocked:
   those set their own ground, and at equal specificity they were winning in
   v1 — which painted a dark numeral onto the ink-filled pill and made the
   active day look like an empty black disc (screenshot-verified). */
#ky-cal-panel .kyc3-c.is-pilled,
#ky-cal-panel .kyc3-c.is-pilled.is-busy,
#ky-cal-panel .kyc3-c.is-pilled.is-blocked{
  color:var(--kyc-btnt);
  background:transparent;
}
#ky-cal-panel .kyc3-c.is-pilled:hover:not(:disabled){ background:transparent; }
#ky-cal-panel .kyc3-c.is-pilled.is-busy .kyc3-g,
#ky-cal-panel .kyc3-c.is-pilled.is-blocked .kyc3-g{
  background:color-mix(in srgb, var(--kyc-btnt) 85%, transparent);
}
#ky-cal-panel .kyc3-c.is-pilled.is-half .kyc3-g{
  border-color:var(--kyc-btnt);
  background:linear-gradient(90deg, var(--kyc-btnt) 0 50%, transparent 50% 100%);
}
#ky-cal-panel .kyc3-c.is-pilled.has-note::after{
  background:var(--kyc-btnt);
  box-shadow:none;
}
/* THE STAGED DAY — a drawn ring that survives the pill moving off it */
#ky-cal-panel .kyc3-c.is-picked{
  box-shadow:inset 0 0 0 2px var(--kyc-ink);
  font-weight:700;
}
/* owner edit mode: every future day stays clickable, including booked ones */
#ky-cal-panel.is-editing .kyc3-c:disabled{ cursor:pointer; opacity:.72; }

/* ═══════════════════════════════════════════════════════════════════════════
   8. THE DETAIL RAIL
   ═══════════════════════════════════════════════════════════════════════════ */
#ky-cal-panel .kyc3-rail{
  min-width:0;
  padding:11px 12px 12px;
  border-radius:16px;
  border:1px solid color-mix(in srgb, var(--kyc-ink) 15%, transparent);
  background:color-mix(in srgb, var(--kyc-ink) 5%, transparent);
}
#ky-cal-panel .kyc3-rh{
  font-size:9px; letter-spacing:.2em; text-transform:uppercase; opacity:.5;
}
#ky-cal-panel .kyc3-rh2{ margin-top:12px; }
#ky-cal-panel .kyc3-rdate{
  margin-top:5px;
  font-size:15px; font-weight:600; letter-spacing:.01em; line-height:1.15;
}
#ky-cal-panel .kyc3-chiprow{
  display:flex; align-items:center; gap:7px; flex-wrap:wrap; margin-top:8px;
}
#ky-cal-panel .kyc3-chip{
  display:inline-flex; align-items:center; gap:5px;
  padding:3px 9px; border-radius:999px;
  font-size:9.5px; letter-spacing:.14em; text-transform:uppercase;
  border:1px solid color-mix(in srgb, var(--kyc-ink) 30%, transparent);
}
#ky-cal-panel .kyc3-chip::before{
  content:""; width:5px; height:5px; border-radius:999px;
  background:currentColor;
}
#ky-cal-panel .kyc3-chip.is-free{
  background:var(--kyc-btn); color:var(--kyc-btnt); border-color:transparent;
}
#ky-cal-panel .kyc3-chip.is-half{
  background:color-mix(in srgb, var(--kyc-mark) 24%, transparent);
  border-color:color-mix(in srgb, var(--kyc-mark) 62%, transparent);
}
#ky-cal-panel .kyc3-chip.is-busy{
  border-color:color-mix(in srgb, var(--kyc-mark) 70%, transparent);
}
#ky-cal-panel .kyc3-wtag{
  font-size:9px; letter-spacing:.16em; text-transform:uppercase; opacity:.45;
}
#ky-cal-panel .kyc3-note{
  margin:9px 0 0; font-size:11px; line-height:1.4; opacity:.82;
  min-height:2.8em;
}

/* ── the slots ──────────────────────────────────────────────────────────
   The document has no times, but the owner's notes do ("Free after 4pm IST").
   ky-cal2.js parses them into these three blocks: open, partly open, or shut.
   A part-day whose note says nothing parseable reports all three as PARTLY —
   never as fully open, because the document has already said the day is not. */
#ky-cal-panel .kyc3-slots{ display:grid; gap:5px; margin-top:6px; }
#ky-cal-panel .kyc3-slots.is-dead{ opacity:.4; }
#ky-cal-panel .kyc3-slot{
  display:flex; align-items:center; gap:8px;
  min-height:34px; padding:0 10px; width:100%;
  border-radius:9px;
  border:1px solid color-mix(in srgb, var(--kyc-ink) 18%, transparent);
  background:transparent; color:var(--kyc-ink);
  font:inherit; font-size:10.5px; text-align:left; cursor:pointer;
  transition:background-color .2s var(--kyc-ease-out), color .18s linear,
             border-color .2s linear, transform .22s var(--kyc-ease),
             opacity .2s linear;
}
#ky-cal-panel .kyc3-slot-g{
  flex:0 0 9px; width:9px; height:9px; border-radius:999px;
  border:1.5px solid currentColor; position:relative;
}
/* open = filled, part = half-filled, shut = hollow with a slash. Shape again. */
#ky-cal-panel .kyc3-slot.is-open .kyc3-slot-g{ background:var(--kyc-mark); border-color:var(--kyc-mark); }
#ky-cal-panel .kyc3-slot.is-part .kyc3-slot-g{
  border-color:var(--kyc-mark);
  background:linear-gradient(90deg, var(--kyc-mark) 0 50%, transparent 50% 100%);
}
#ky-cal-panel .kyc3-slot.is-shut .kyc3-slot-g::after{
  content:""; position:absolute; left:-2px; right:-2px; top:50%;
  height:1px; background:currentColor; transform:translateY(-50%) rotate(-40deg);
}
#ky-cal-panel .kyc3-slot-l{
  letter-spacing:.14em; text-transform:uppercase; flex:1 1 auto;
}
#ky-cal-panel .kyc3-slot-t{ opacity:.55; letter-spacing:.04em; flex:0 0 auto; }
#ky-cal-panel .kyc3-slot:hover:not(:disabled){
  background:color-mix(in srgb, var(--kyc-ink) 12%, transparent);
  transform:translateX(2px);
}
#ky-cal-panel .kyc3-slot:active:not(:disabled){ transform:translateX(0) scale(.98); }
#ky-cal-panel .kyc3-slot:disabled{ opacity:.42; cursor:not-allowed; }
#ky-cal-panel .kyc3-slot.is-on{
  background:var(--kyc-btn); color:var(--kyc-btnt); border-color:transparent;
}
#ky-cal-panel .kyc3-slot.is-on .kyc3-slot-g{
  background:var(--kyc-btnt); border-color:var(--kyc-btnt);
}
#ky-cal-panel .kyc3-slot.is-on .kyc3-slot-t{ opacity:.75; }
#ky-cal-panel .kyc3-slot:focus-visible{ outline:2px solid var(--kyc-ink); outline-offset:2px; }

/* ── the two-clock line ─────────────────────────────────────────────────
   The document names the OWNER's zone; the visitor's comes from their own
   machine. Both offsets are read FOR THE DAY IN QUESTION, so a booking on the
   far side of the visitor's DST change is quoted correctly. */
#ky-cal-panel .kyc3-tz{
  margin-top:11px; padding-top:9px;
  border-top:1px solid color-mix(in srgb, var(--kyc-ink) 15%, transparent);
  display:grid; gap:4px;
}
#ky-cal-panel .kyc3-tzr{
  display:flex; align-items:baseline; gap:7px;
  font-size:10px; letter-spacing:.02em;
}
#ky-cal-panel .kyc3-tzr b{
  flex:0 0 4.8em;
  font-weight:400; font-size:8.5px; letter-spacing:.16em;
  text-transform:uppercase; opacity:.5;
}
/* a real element, so it can shrink: the value is long enough to need wrapping
   in a 248px rail and an anonymous flex item cannot take min-width:0 */
#ky-cal-panel .kyc3-tzv{ flex:1 1 auto; min-width:0; line-height:1.35; }
#ky-cal-panel .kyc3-tzr-you{ color:var(--kyc-ink); }
#ky-cal-panel .kyc3-tzr-you b{ opacity:.68; }

/* ── the booking summary ───────────────────────────────────────────────── */
#ky-cal-panel .kyc3-sum{
  margin-top:12px; padding:9px 10px 10px;
  border-radius:12px;
  border:1px dashed color-mix(in srgb, var(--kyc-ink) 28%, transparent);
  transition:border-color .3s var(--kyc-ease-out),
             background-color .3s var(--kyc-ease-out);
}
#ky-cal-panel .kyc3-sum.is-armed{
  border-style:solid;
  border-color:color-mix(in srgb, var(--kyc-ink) 55%, transparent);
  background:color-mix(in srgb, var(--kyc-glow) 12%, transparent);
}
#ky-cal-panel .kyc3-sum .kyc3-rh2{ margin-top:0; }
#ky-cal-panel .kyc3-sumv{
  margin:5px 0 9px; font-size:11px; line-height:1.35; min-height:2.7em;
}
/* the primary action wears the site's own button vocabulary — rounded-full,
   ink fill, accent label — which is also the pair that is already correct at
   both ink poles */
#ky-cal-panel .kyc3-go{
  display:flex; align-items:center; justify-content:center; gap:8px;
  width:100%; min-height:40px; padding:0 14px;
  border:0; border-radius:999px;
  background:var(--kyc-btn); color:var(--kyc-btnt);
  font:inherit; font-size:10px; font-weight:700;
  letter-spacing:.18em; text-transform:uppercase; cursor:pointer;
  transition:transform .24s var(--kyc-ease), opacity .2s linear,
             box-shadow .24s var(--kyc-ease-out);
}
#ky-cal-panel .kyc3-go i{
  font-style:normal; display:inline-block;
  transition:transform .3s var(--kyc-ease);
}
#ky-cal-panel .kyc3-go:hover:not(:disabled){
  box-shadow:0 6px 18px -8px color-mix(in srgb, var(--kyc-ink) 70%, transparent);
}
#ky-cal-panel .kyc3-go:hover:not(:disabled) i{ transform:translate(3px,-3px); }
#ky-cal-panel .kyc3-go:active:not(:disabled){ transform:scale(.97); }
#ky-cal-panel .kyc3-go:disabled{ opacity:.34; cursor:not-allowed; }
#ky-cal-panel .kyc3-go:focus-visible{ outline:2px solid var(--kyc-ink); outline-offset:3px; }

/* ═══════════════════════════════════════════════════════════════════════════
   9. FOOT — legend + hint
   ═══════════════════════════════════════════════════════════════════════════ */
#ky-cal-panel .kyc3-foot{
  margin-top:12px; padding-top:10px;
  border-top:1px solid color-mix(in srgb, var(--kyc-ink) 16%, transparent);
}
#ky-cal-panel .kyc3-legend{
  display:flex; flex-wrap:wrap; gap:5px 14px;
  font-size:9.5px; letter-spacing:.08em; text-transform:uppercase; opacity:.76;
}
#ky-cal-panel .kyc3-legend span{ display:flex; align-items:center; gap:6px; }
#ky-cal-panel .kyc3-legend i{
  position:relative; width:16px; height:16px; border-radius:999px;
  flex:0 0 16px;
  background:color-mix(in srgb, var(--kyc-ink) 10%, transparent);
}
#ky-cal-panel .kyc3-legend i .kyc3-g{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  display:block;
}
#ky-cal-panel .kyc3-legend i.is-busy{ background:color-mix(in srgb, var(--kyc-mark) 22%, transparent); }
#ky-cal-panel .kyc3-legend i.is-busy .kyc3-g{
  width:60%; height:1.5px; border-radius:2px; background:var(--kyc-mark);
  transform:translate(-50%,-50%) rotate(-24deg);
}
#ky-cal-panel .kyc3-legend i.is-blocked{ background:transparent;
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--kyc-ink) 24%, transparent); }
#ky-cal-panel .kyc3-legend i.is-blocked .kyc3-g{
  width:46%; height:1px; background:color-mix(in srgb, var(--kyc-ink) 62%, transparent);
  transform:translate(-50%,-50%) rotate(-24deg);
}
#ky-cal-panel .kyc3-legend i.is-half .kyc3-g{
  width:7px; height:7px; border-radius:999px;
  border:1px solid var(--kyc-mark);
  background:linear-gradient(90deg, var(--kyc-mark) 0 50%, transparent 50% 100%);
}
#ky-cal-panel .kyc3-legend i.has-note .kyc3-g{
  width:3px; height:3px; border-radius:999px; background:var(--kyc-glow);
  box-shadow:0 0 0 1px color-mix(in srgb, var(--kyc-ink) 22%, transparent);
}
#ky-cal-panel .kyc3-hint{
  margin-top:8px; min-height:2.6em;
  font-size:11px; line-height:1.35; opacity:.8;
}
#ky-cal-panel .kyc3-hint b{ font-weight:600; opacity:1; }

/* ═══════════════════════════════════════════════════════════════════════════
   10. OWNER EDIT BAR + THE DEV-PANEL ROW
   ═══════════════════════════════════════════════════════════════════════════ */
#ky-cal-panel .kyc3-edit{ display:none; }
#ky-cal-panel.is-editing .kyc3-edit{
  display:block; margin-top:12px; padding:10px;
  border-radius:14px;
  border:1px dashed color-mix(in srgb, var(--kyc-ink) 38%, transparent);
  background:color-mix(in srgb, var(--kyc-ink) 6%, transparent);
}
#ky-cal-panel .kyc3-edit p{
  margin:0 0 8px; font-size:10.5px; line-height:1.45; letter-spacing:.02em;
}
#ky-cal-panel .kyc3-btns{ display:flex; flex-wrap:wrap; gap:6px; }
#ky-cal-panel .kyc3-edit button{
  min-height:40px; padding:0 14px; border-radius:999px;
  border:1px solid color-mix(in srgb, var(--kyc-ink) 40%, transparent);
  background:transparent; color:var(--kyc-ink);
  font:inherit; font-size:9.5px; letter-spacing:.14em; text-transform:uppercase;
  cursor:pointer;
  transition:background-color .2s var(--kyc-ease-out), color .18s linear,
             transform .22s var(--kyc-ease);
}
#ky-cal-panel .kyc3-edit button:hover{ background:var(--kyc-btn); color:var(--kyc-btnt); }
#ky-cal-panel .kyc3-edit button:active{ transform:scale(.96); }

/* the switch injected into the #ky-sw dev panel — that panel is dark chrome
   with its own vocabulary, so this row speaks it rather than the site's */
#ky-sw .ky-cal-devrow{
  display:flex; align-items:center; gap:8px; min-height:44px;
  padding:7px 10px; cursor:pointer;
  font-size:11px; letter-spacing:.04em;
  border-top:1px solid rgba(255,255,255,.14);
}
#ky-sw .ky-cal-devrow .kyc3-sw{
  margin-left:auto; width:26px; height:15px; border-radius:999px;
  background:rgba(255,255,255,.22); position:relative; flex:0 0 26px;
  transition:background-color .2s linear;
}
#ky-sw .ky-cal-devrow .kyc3-sw::after{
  content:""; position:absolute; top:2px; left:2px;
  width:11px; height:11px; border-radius:999px; background:#fff;
  transition:transform .24s var(--kyc-ease);
}
#ky-sw .ky-cal-devrow.on .kyc3-sw{ background:#4ade80; }
#ky-sw .ky-cal-devrow.on .kyc3-sw::after{ transform:translateX(11px); }

/* screen-reader-only live region */
#ky-cal-panel .kyc3-sr{
  position:absolute !important; width:1px; height:1px;
  margin:-1px; padding:0; overflow:hidden; white-space:nowrap;
  clip:rect(0 0 0 0); clip-path:inset(50%); border:0;
}

/* ═══════════════════════════════════════════════════════════════════════════
   11. THE INJECTED CONTACT-FORM DATE FIELD
   The contact band is a hardcoded near-black gradient with light-on-dark
   inputs, and ky-glassify.css's !important input ink stays in force there in
   both modes — so this field is tuned to that band, not to the panel.
   ═══════════════════════════════════════════════════════════════════════════ */
.ky-cal-field label{
  display:block; margin:0 0 5px 2px;
  font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--color-text-bg, #d1d1c7); opacity:.8;
}
.ky-cal-field input{
  /* mirrors the sibling inputs' Tailwind classes as real CSS, so the field
     keeps its look if React re-renders around it */
  width:100%;
  border-radius:.75rem;
  padding:.75rem 1rem;
  background:rgba(255,255,255,.05);
  border:1px solid rgba(255,255,255,.1);
  color:var(--color-text-bg, #d1d1c7);
  font:inherit;
  font-size:var(--text-base, 15px);
  font-weight:400;
  transition:box-shadow .15s linear, border-color .15s linear;
}
.ky-cal-field input:focus{
  outline:none;
  box-shadow:0 0 0 2px rgba(255,255,255,.2);
}
.ky-cal-field input::-webkit-calendar-picker-indicator{
  filter:invert(1); opacity:.5; cursor:pointer;
}
.ky-cal-field input::-webkit-calendar-picker-indicator:hover{ opacity:.9; }

/* ═══════════════════════════════════════════════════════════════════════════
   12. PER-PLATE PERSONALISATION
   The plate key is published by ky-cal2.js off ky:wall-theme. Everything here
   is PERSONALITY ONLY — nothing below carries state, so a plate that never
   arrives loses nothing. Small, and only on the pieces that already glow.
   ═══════════════════════════════════════════════════════════════════════════ */
/* singularity — the black hole. The active day acquires an accretion halo and
   the staged ring picks up the violet, in the spirit of the DustText warp the
   wallpaper lane runs on the type. */
html.ky-wallmode #ky-cal-panel[data-kyc-plate="singularity"] .kyc3-pill{
  box-shadow:0 0 0 3px color-mix(in srgb, var(--kyc-glow) 26%, transparent),
             0 0 26px -2px color-mix(in srgb, var(--kyc-glow) 60%, transparent);
}
html.ky-wallmode #ky-cal-panel[data-kyc-plate="singularity"] .kyc3-sum.is-armed{
  box-shadow:0 0 24px -10px color-mix(in srgb, var(--kyc-glow) 75%, transparent);
}
/* ember-ring — the heat rails run hot */
html.ky-wallmode #ky-cal-panel[data-kyc-plate="ember-ring"] .kyc3-heat,
html.ky-wallmode #ky-cal-panel[data-kyc-plate="ember-ring"] .kyc3-meter i{
  background:color-mix(in srgb, var(--kyc-glow) 70%, var(--kyc-mark));
}
/* courtyard-rain / starfield-drift — cool plates: the note ticks and the
   today ring take the plate's own light so the grid is not the only warm
   thing on a cold frame */
html.ky-wallmode #ky-cal-panel[data-kyc-plate="courtyard-rain"] .kyc3-c.is-today::before,
html.ky-wallmode #ky-cal-panel[data-kyc-plate="starfield-drift"] .kyc3-c.is-today::before{
  border-color:color-mix(in srgb, var(--kyc-glow) 70%, transparent);
  border-style:solid;
}
/* forest-snow keeps the house honey and needs nothing: it IS the base costume. */

/* ═══════════════════════════════════════════════════════════════════════════
   13. RESPONSIVE
   The rail drops under the calendar before the panel would have to squeeze
   either of them. The breakpoint is on the VIEWPORT, and the panel is
   min(724px, 100vw - 24px), so the two can never disagree.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width:768px){
  #ky-cal-panel{
    width:min(430px, 100vw - 20px);
    --kyc-cell:40px;
    --kyc-wk:22px;
    padding:13px 12px 11px;
  }
  #ky-cal-panel .kyc3-body{ grid-template-columns:minmax(0,1fr); gap:12px; }
  #ky-cal-panel .kyc3-tape-pips{ gap:2px; }
  #ky-cal-panel .kyc3-pip{ height:28px; border-radius:5px; }
  #ky-cal-panel .kyc3-pip-l{ font-size:7.5px; letter-spacing:0; }
  /* three across, stacked inside: a slot row cannot hold a glyph, a tracked
     label and a time range in a third of a 406px card */
  #ky-cal-panel .kyc3-slots{ grid-template-columns:repeat(3,1fr); }
  #ky-cal-panel .kyc3-slot{ flex-direction:column; align-items:flex-start; gap:3px; padding:7px 8px; }
  #ky-cal-panel .kyc3-slot-l{ flex:0 0 auto; }
  #ky-cal-panel .kyc3-slot-t{ font-size:9px; }
  #ky-cal-panel .kyc3-legend{ font-size:9px; gap:4px 10px; }
}
@media (max-width:420px){
  /* below the touch floor on purpose: at 420px the alternative is a grid that
     scrolls sideways, and a 38px cell in a 7-across month is still a ~50px
     wide target. The T key and PageUp/PageDown keep every function the two
     hidden controls carried. */
  #ky-cal-panel{ --kyc-gap:3px; --kyc-cell:38px; }
  #ky-cal-panel .kyc3-today{ display:none; }
}
@media (max-height:660px){
  #ky-cal-panel{ --kyc-cell:36px; }
  #ky-cal-panel .kyc3-tape{ display:none; }    /* the scrubber still turns pages */
}

/* ═══════════════════════════════════════════════════════════════════════════
   14. A11Y
   ═══════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce){
  /* the JS already takes every instant path under this query; this is the
     belt-and-braces half, so a stale class can never animate for a visitor who
     asked for stillness */
  #ky-cal,
  #ky-cal *,
  #ky-cal *::before,
  #ky-cal *::after,
  #ky-cal-scrim,
  #ky-cal-panel,
  #ky-cal-panel *,
  #ky-cal-panel *::before,
  #ky-cal-panel *::after,
  #ky-sw .ky-cal-devrow .kyc3-sw,
  #ky-sw .ky-cal-devrow .kyc3-sw::after{
    transition-duration:.001s !important;
    animation:none !important;
  }
  #ky-cal-panel{ transform:scale(1); }
  #ky-cal-panel .kyc3-x:hover,
  #ky-cal-panel .kyc3-arrow:hover:not(:disabled),
  #ky-cal-panel .kyc3-today:hover:not(:disabled),
  #ky-cal-panel .kyc3-pip:hover:not(:disabled),
  #ky-cal-panel .kyc3-c:hover:not(:disabled),
  #ky-cal-panel .kyc3-slot:hover:not(:disabled),
  #ky-cal-panel .kyc3-go:hover:not(:disabled),
  #ky-cal-panel .kyc3-go:hover:not(:disabled) i{ transform:none; }
}

@media (prefers-reduced-transparency: reduce){
  #ky-cal-scrim{
    background:color-mix(in srgb, var(--color-foreground,#14110A) 80%, transparent);
  }
  html.ky-wallmode #ky-cal-scrim[data-kyc-dark="1"]{
    background:color-mix(in srgb, #14110A 84%, transparent);
  }
  /* liquid-glass.css already forces .lg-surface to an opaque
     --color-background here — correct at the ink pole, but on a DARK PLATE the
     ink has lifted to cream and --color-background has not, so that plate has
     to be floored at the house ink constant instead. */
  html.ky-wallmode #ky-cal-panel[data-kyc-dark="1"]{
    background:color-mix(in srgb, #14110A 92%, var(--color-accent-200,#E3AC33)) !important;
  }
}

@media (forced-colors: active){
  #ky-cal-panel{ border:1px solid CanvasText; background:Canvas; }
  #ky-cal-panel .kyc3-pill{ background:Highlight; }
  #ky-cal-panel .kyc3-c.is-pilled{ color:HighlightText; }
  #ky-cal-panel .kyc3-c .kyc3-g,
  #ky-cal-panel .kyc3-heat,
  #ky-cal-panel .kyc3-meter i,
  #ky-cal-panel .kyc3-pip-bar,
  #ky-cal .kyc2-d.is-busy::after,
  #ky-cal .kyc2-d.is-half::after{
    background:CanvasText; forced-color-adjust:none;
  }
  #ky-cal-panel .kyc3-c.is-picked{ box-shadow:inset 0 0 0 2px CanvasText; }
}
