/* <djjs-sadhna-dial> (assets/js/sadhna-dial.js, includes/shell/dial.php): the Akhand Sadhna dial and its one shared sheet.
   Tokens only: the --ds-* values of assets/css/ds/tokens.css (Temple Dark under :root.dark, Temple Dawn otherwise). The two dial
   sizes are the spec's own (64 px on the phone bar, lifted 12 px; 48 px in the header), kept as custom properties here.

   The dial reads like a lamp: its ring is sixty small shards, one per minute, the first at the top and the rest counter-clockwise.
   An hour nobody has taken is an unlit ring that breathes slowly; a held hour has a steady glow; while in sadhna the minutes sat light
   up one after another and the current minute's shard powers up, the ring completing as the hour ends. No countdown on the face (the
   sheet keeps the timer). Under prefers-reduced-motion nothing moves. No badges, streak marks or counters on the dial. */

djjs-sadhna-dial {
  --dial-plate: url("../img/dial/plate-light.webp");   /* a small jewelled medallion rendered offline (tools/blender/generate_sadhna_dial.py): burnished gold, a channel for the shards, a setting for the live jewel */
  --dial-size: 48px;
  --dial-lift: 0px;
  display: inline-flex; flex: none; align-items: center; justify-content: center; position: relative;
}
djjs-sadhna-dial[data-variant="bar"] {
  --dial-size: 64px;
  --dial-lift: 12px;
  display: flex; inline-size: 100%; block-size: var(--ds-tabbar-h, 60px); align-items: flex-start;
}
djjs-sadhna-dial[data-variant="bar"][data-state="insadhna"] { --dial-lift: 16px; }

:is(.dark, .ds-theme-dark) djjs-sadhna-dial { --dial-plate: url("../img/dial/plate-dark.webp"); }

/* ------------------------------------------------------------ the dial */
.ds-dial__btn {
  position: relative; display: grid; place-items: center; flex: none; box-sizing: border-box;
  inline-size: var(--dial-size); block-size: var(--dial-size);
  min-inline-size: var(--ds-touch, 44px); min-block-size: var(--ds-touch, 44px);
  margin: 0; padding: 0; border: 0; border-radius: 50%;
  background: var(--dial-plate) center / 100% 100% no-repeat, var(--ds-surface-raised); color: var(--ds-accent);
  font: inherit; text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
  top: calc(-1 * var(--dial-lift));
  --dial-glow: color-mix(in srgb, var(--ds-accent) 34%, transparent);
  box-shadow: var(--ds-shadow-2), 0 0 var(--ds-space-3) 0 var(--dial-glow);
  transition: top var(--ds-dur-base) var(--ds-ease-gentle), background-color var(--ds-dur-base), color var(--ds-dur-base), opacity var(--ds-dur-base);
}
.ds-dial__btn:focus-visible { outline: 2px solid var(--ds-focus); outline-offset: 3px; }
.ds-dial__btn:active { transform: scale(.97); }
/* it answers a pointer: the plate rises a little, the shards brighten and the jewel flares */
.ds-dial__btn { transition: top var(--ds-dur-base) var(--ds-ease-gentle), transform var(--ds-dur-base) var(--ds-ease-gentle), opacity var(--ds-dur-base), box-shadow var(--ds-dur-base); }
@media (hover: hover) and (pointer: fine) {
  .ds-dial__btn:hover { transform: scale(1.06); }
  .ds-dial__btn:hover .ds-dial__ray-dim { opacity: .5; }
  .ds-dial__btn:hover .ds-dial__jewel { filter: drop-shadow(0 0 2.6px var(--dial-hi)) brightness(1.18); }
}
.ds-dial__btn:focus-visible .ds-dial__ray-dim { opacity: .5; }
.ds-dial__face { grid-area: 1 / 1; inline-size: 100%; block-size: 100%; overflow: visible; --dial-lit: var(--ds-accent); --dial-hi: var(--ds-accent); --dial-jewel: color-mix(in srgb, var(--ds-accent) 72%, var(--ds-action)); --dial-table: color-mix(in srgb, var(--ds-accent) 60%, white); }
:is(.dark, .ds-theme-dark) .ds-dial__face { --dial-hi: color-mix(in srgb, var(--ds-accent) 55%, white); }
:root:not(.dark) .ds-dial__face { --dial-hi: color-mix(in srgb, var(--ds-accent) 78%, white); }
/* the ring: sixty small shards, one per minute, the first at the top and the rest counter-clockwise (assets/js/sadhna-dial.js lights them) */
.ds-dial__ray-dim { fill: currentColor; opacity: .26; }
.ds-dial__ray-soft { fill: currentColor; opacity: .42; }
.ds-dial__ray-lit { fill: var(--dial-lit); filter: drop-shadow(0 0 1.1px var(--dial-lit)); }
.ds-dial__ray-now { fill: var(--dial-hi); filter: drop-shadow(0 0 2.4px var(--dial-hi)); }
/* the jewel in the plate's setting: an amber stone of eight facets, alive even when nobody is sitting */
.ds-dial__jewel { fill: var(--dial-jewel); opacity: .86; filter: drop-shadow(0 0 1.4px var(--dial-jewel)); transition: filter var(--ds-dur-base), opacity var(--ds-dur-base); }
.ds-dial__table { fill: var(--dial-table); fill-opacity: .9; }
.ds-dial__core { fill: var(--dial-hi); opacity: .9; }
.ds-dial__glint { fill: white; opacity: 0; transform-box: fill-box; transform-origin: center; }
.ds-dial__ripple { fill: none; stroke: var(--dial-lit); stroke-width: 1.1; opacity: 0; transform-origin: 32px 32px; transform-box: view-box; pointer-events: none; }

/* open (and while the hour is still loading): the unlit shards, a gentle breathing glow */
@keyframes ds-dial-breathe {
  0%, 100% { box-shadow: var(--ds-shadow-2), 0 0 var(--ds-space-2) 0 color-mix(in srgb, var(--ds-accent) 20%, transparent); }
  50% { box-shadow: var(--ds-shadow-2), 0 0 var(--ds-space-6) var(--ds-space-1) color-mix(in srgb, var(--ds-accent) 52%, transparent); }
}
/* the minute's own shard powers up: it breathes between a steady light and a brighter one while it grows */
@keyframes ds-dial-power { 0%, 100% { opacity: .82; } 50% { opacity: 1; } }
/* the core of a lit dial is a small flame of light */
@keyframes ds-dial-core { 0%, 100% { opacity: .85; } 50% { opacity: 1; } }
/* an invitation, not an alarm: the jewel breathes, a ring of light drifts outward now and then, and a glint crosses the stone */
@keyframes ds-dial-jewel { 0%, 100% { opacity: .78; } 50% { opacity: 1; } }
@keyframes ds-dial-ripple { 0% { transform: scale(.72); opacity: 0; } 10% { opacity: .5; } 62%, 100% { transform: scale(1.5); opacity: 0; } }
@keyframes ds-dial-glint { 0%, 70%, 100% { opacity: 0; transform: scale(.4) rotate(0deg); } 78% { opacity: .95; transform: scale(1.1) rotate(20deg); } 88% { opacity: 0; transform: scale(.5) rotate(45deg); } }
@media (prefers-reduced-motion: no-preference) {
  djjs-sadhna-dial[data-state="open"] .ds-dial__btn { animation: ds-dial-breathe 5s ease-in-out infinite; }
  .ds-dial__ray-now { animation: ds-dial-power 2.6s ease-in-out infinite; }
  djjs-sadhna-dial:not([data-state="unavailable"]):not([data-state="joining"]) .ds-dial__jewel { animation: ds-dial-jewel 4.2s ease-in-out infinite; }
  djjs-sadhna-dial:not([data-state="unavailable"]):not([data-state="insadhna"]):not([data-state="done"]) .ds-dial__ripple { animation: ds-dial-ripple 6.5s ease-out infinite 1.4s; }
  djjs-sadhna-dial:not([data-state="unavailable"]) .ds-dial__glint { animation: ds-dial-glint 7s ease-in-out infinite 2s; }
}

/* held, and the hour just completed: a steady glow, the shards a little clearer */
djjs-sadhna-dial[data-state="held"] .ds-dial__ray-dim, djjs-sadhna-dial[data-state="done"] .ds-dial__ray-dim { opacity: .4; }
djjs-sadhna-dial[data-state="held"] .ds-dial__btn, djjs-sadhna-dial[data-state="done"] .ds-dial__btn {
  --dial-glow: color-mix(in srgb, var(--ds-accent) 46%, transparent);
  box-shadow: var(--ds-shadow-2), 0 0 var(--ds-space-5) var(--ds-space-1) var(--dial-glow);
}

/* the sitting is opening: the shards wake together, once (still under reduced motion) */
@keyframes ds-dial-wake { 0% { opacity: .26; } 45% { opacity: .75; } 100% { opacity: .26; } }
@media (prefers-reduced-motion: no-preference) {
  djjs-sadhna-dial[data-state="joining"] .ds-dial__ray-dim { animation: ds-dial-wake 1.4s var(--ds-ease-gentle) 1 both; }
}
djjs-sadhna-dial[data-state="joining"] .ds-dial__btn { cursor: progress; }

/* in sadhna: the minutes sat are lit, counter-clockwise, and the dial glows from within; the minute's shard powers up */
djjs-sadhna-dial[data-state="insadhna"] .ds-dial__btn {
  --dial-glow: color-mix(in srgb, var(--ds-accent) 58%, transparent);
  box-shadow: var(--ds-shadow-3), 0 0 var(--ds-space-5) var(--ds-space-1) var(--dial-glow);
}
djjs-sadhna-dial[data-state="insadhna"] .ds-dial__jewel { opacity: 1; filter: drop-shadow(0 0 3px var(--dial-hi)) brightness(1.2); }
djjs-sadhna-dial[data-state="insadhna"] .ds-dial__core { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  djjs-sadhna-dial[data-state="insadhna"] .ds-dial__core { animation: ds-dial-core 3.2s ease-in-out infinite; }
}
/* close to the hour's end: the ring is nearly whole and the light deepens */
djjs-sadhna-dial[data-near="1"][data-state="insadhna"] .ds-dial__btn { --dial-glow: color-mix(in srgb, var(--ds-accent) 78%, transparent); box-shadow: var(--ds-shadow-3), 0 0 var(--ds-space-6) var(--ds-space-2) var(--dial-glow); }
djjs-sadhna-dial[data-near="1"] .ds-dial__ray-lit { filter: drop-shadow(0 0 2px var(--dial-hi)); }

/* the hour is complete: every shard lit, one soft bloom, then a steady radiance */
@keyframes ds-dial-bloom { 0% { filter: drop-shadow(0 0 1px var(--dial-lit)); } 45% { filter: drop-shadow(0 0 5px var(--dial-hi)) brightness(1.25); } 100% { filter: drop-shadow(0 0 2px var(--dial-hi)); } }
djjs-sadhna-dial[data-state="done"] .ds-dial__ray-lit { filter: drop-shadow(0 0 2px var(--dial-hi)); }
djjs-sadhna-dial[data-state="done"] .ds-dial__core { opacity: 1; }
djjs-sadhna-dial[data-state="done"] .ds-dial__jewel { opacity: 1; filter: drop-shadow(0 0 3px var(--dial-hi)) brightness(1.2); }
@media (prefers-reduced-motion: no-preference) {
  djjs-sadhna-dial[data-state="done"] .ds-dial__ray-lit { animation: ds-dial-bloom 1.8s var(--ds-ease-gentle) 1 both; }
}

/* signed out: the same invitation, a quieter glow */
djjs-sadhna-dial[data-state="signedout"] .ds-dial__btn { box-shadow: var(--ds-shadow-2), 0 0 var(--ds-space-3) 0 color-mix(in srgb, var(--ds-accent) 30%, transparent); }

/* unavailable: dimmed */
djjs-sadhna-dial[data-state="unavailable"] .ds-dial__btn { opacity: .55; box-shadow: var(--ds-shadow-1); }

.ds-dial-live, .ds-dial-sr {
  position: absolute; inline-size: 1px; block-size: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
html.ds-dial-open { overflow: hidden; }

/* ------------------------------------------------------------ the sheet */
dialog.ds-dialsheet {
  --sh-bg: var(--ds-surface-raised);
  --sh-sunken: var(--ds-surface-sunken);
  --sh-ink: var(--ds-text);
  --sh-muted: var(--ds-text-muted);
  --sh-line: var(--ds-border);
  --sh-accent: var(--ds-accent);
  --sh-pad: var(--ds-space-5);
  position: fixed; inset: auto 0 0 0; margin: 0; padding: 0; box-sizing: border-box;
  inline-size: 100%; max-inline-size: 100%; block-size: auto; max-block-size: 92dvh;
  border: 1px solid var(--sh-line); border-block-end: 0; border-radius: var(--ds-radius-lg) var(--ds-radius-lg) 0 0;
  background: var(--sh-bg); color: var(--sh-ink); box-shadow: var(--ds-shadow-3);
  font-family: var(--ds-font-ui); font-size: var(--ds-text-md); line-height: var(--ds-leading-normal);
  overflow: hidden; overscroll-behavior: contain; z-index: var(--ds-z-dialog);
}
dialog.ds-dialsheet[open] { display: flex; flex-direction: column; animation: ds-dialsheet-rise var(--ds-dur-base) var(--ds-ease-gentle); }
dialog.ds-dialsheet::backdrop { background: color-mix(in srgb, var(--sh-sunken) 70%, transparent); -webkit-backdrop-filter: blur(var(--ds-blur-sm)); backdrop-filter: blur(var(--ds-blur-sm)); }
@keyframes ds-dialsheet-rise { from { transform: translateY(100%); } }
@keyframes ds-dialsheet-fade { from { opacity: 0; transform: translateY(calc(-1 * var(--ds-space-2))); } }

.ds-dialsheet__grip { display: block; flex: none; inline-size: var(--ds-space-8); block-size: var(--ds-space-1); margin: var(--ds-space-2) auto 0; border-radius: var(--ds-radius-pill); background: var(--sh-line); }
.ds-dialsheet__head { display: flex; align-items: center; justify-content: space-between; gap: var(--ds-space-4); flex: none; padding: var(--ds-space-3) var(--sh-pad) var(--ds-space-2) var(--sh-pad); }
.ds-dialsheet__title { margin: 0; font-family: var(--ds-font-display); font-size: var(--ds-text-2xl); font-weight: 600; line-height: var(--ds-leading-tight); color: var(--sh-ink); }
.ds-dialsheet__title:focus { outline: none; }
.ds-dialsheet__x {
  position: relative; display: grid; place-items: center; flex: none; inline-size: var(--ds-touch, 44px); block-size: var(--ds-touch, 44px);
  margin: 0; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--sh-muted); cursor: pointer;
}
.ds-dialsheet__x:hover { color: var(--sh-ink); background: var(--sh-sunken); }
.ds-dialsheet__body { display: grid; justify-items: center; gap: var(--ds-space-4); padding: var(--ds-space-2) var(--sh-pad) calc(var(--sh-pad) + env(safe-area-inset-bottom, 0px)); overflow-y: auto; overscroll-behavior: contain; min-block-size: 0; }

/* the ring of 24 hours, the hour or the countdown in its centre */
.ds-dialsheet__ringwrap { position: relative; inline-size: min(100%, 15rem); aspect-ratio: 1; }
.ds-ring { display: block; inline-size: 100%; block-size: 100%; overflow: visible; }
.ds-ring__idle { fill: none; stroke: var(--sh-line); stroke-width: 2; stroke-dasharray: 3 4; }
.ds-ring__seg { stroke-linejoin: round; }
.ds-ring__seg.is-held { fill: var(--ds-accent); }
.ds-ring__seg.is-open { fill: none; stroke: var(--ds-accent); stroke-width: 1.5; stroke-dasharray: 3 3; }
.ds-ring__seg.is-now.is-held { stroke: var(--sh-ink); stroke-width: 2; }
.ds-ring__seg.is-now.is-open { stroke-width: 2.5; stroke-dasharray: none; }
.ds-ring__seg.is-live { filter: drop-shadow(0 0 6px var(--ds-accent)); }
.ds-ring__mine { fill: var(--sh-ink); }
.ds-ring__now { fill: var(--sh-ink); }
.ds-ring__lab { fill: var(--sh-muted); font-family: var(--ds-font-ui); font-size: 13px; }
.ds-dialsheet__core { position: absolute; inset: 20%; display: grid; place-content: center; justify-items: center; text-align: center; pointer-events: none; }
.ds-dialsheet__clock { white-space: nowrap; font-family: var(--ds-font-display); font-size: var(--ds-text-2xl); font-weight: 600; line-height: 1; color: var(--sh-ink); font-variant-numeric: lining-nums tabular-nums; }
.ds-dialsheet__sub { margin-block-start: var(--ds-space-1); font-size: var(--ds-text-sm); color: var(--sh-muted); }

.ds-dialsheet__text { display: grid; gap: var(--ds-space-2); justify-items: center; text-align: center; max-inline-size: 28rem; }
.ds-dialsheet__lead { margin: 0; font-family: var(--ds-font-display); font-size: var(--ds-text-xl); font-weight: 600; line-height: var(--ds-leading-tight); color: var(--sh-ink); }
.ds-dialsheet__detail, .ds-dialsheet__fellow { margin: 0; color: var(--sh-muted); }
.ds-dialsheet__held { margin: 0; font-size: var(--ds-text-sm); color: var(--sh-muted); font-variant-numeric: lining-nums tabular-nums; }
.ds-dialsheet__alert { margin: 0; padding: var(--ds-space-2) var(--ds-space-3); border-radius: var(--ds-radius-sm); border: 1px solid var(--ds-danger); color: var(--ds-danger); font-size: var(--ds-text-sm); }
.ds-dialsheet__confirm p { margin: 0; color: var(--sh-ink); }

.ds-dialsheet__next { list-style: none; display: flex; flex-wrap: wrap; justify-content: center; gap: var(--ds-space-2); margin: var(--ds-space-1) 0 0; padding: 0; }
.ds-dialsheet__next li { display: inline-flex; align-items: center; gap: var(--ds-space-2); padding: var(--ds-space-1) var(--ds-space-3); border: 1px solid var(--sh-line); border-radius: var(--ds-radius-pill); font-size: var(--ds-text-sm); }
.ds-dialsheet__next .is-open { border-style: dashed; }
.ds-dialsheet__next .is-held { background: color-mix(in srgb, var(--ds-accent) 14%, transparent); }
.ds-dialsheet__t { font-variant-numeric: lining-nums tabular-nums; }
.ds-dialsheet__m { color: var(--sh-muted); }

.ds-dialsheet__actions { display: grid; gap: var(--ds-space-2); inline-size: 100%; max-inline-size: 28rem; }
.ds-dialsheet__btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; inline-size: 100%;
  min-block-size: calc(var(--ds-touch, 44px) + var(--ds-space-1)); margin: 0; padding: var(--ds-space-2) var(--ds-space-5);
  border: 1px solid transparent; border-radius: var(--ds-radius-md); font: inherit; font-weight: 600; text-decoration: none; cursor: pointer;
}
.ds-dialsheet__btn--primary { background: var(--ds-action); color: var(--ds-action-contrast); border-color: color-mix(in srgb, var(--ds-accent) 45%, transparent); }
.ds-dialsheet__btn--outline { background: transparent; color: var(--sh-ink); border-color: var(--sh-accent); }
.ds-dialsheet__btn--quiet { background: transparent; color: var(--sh-ink); border-color: var(--sh-line); }
.ds-dialsheet__btn:disabled { cursor: progress; opacity: .7; }
@media (hover: hover) and (pointer: fine) {
  .ds-dialsheet__btn--primary:hover { background: color-mix(in srgb, var(--ds-action) 86%, var(--ds-text)); }
  .ds-dialsheet__btn--outline:hover, .ds-dialsheet__btn--quiet:hover { background: var(--sh-sunken); }
}
.ds-dialsheet__link { display: inline-flex; align-items: center; min-block-size: var(--ds-touch, 44px); color: var(--sh-accent); text-underline-offset: .2em; }
.ds-dialsheet :focus-visible { outline: 2px solid var(--ds-focus); outline-offset: 2px; }

/* a popover under the header dial from 640 px up (placed by the script: --ds-dial-top, --ds-dial-right) */
@media (min-width: 640px) {
  dialog.ds-dialsheet[data-placement="popover"] {
    inset: var(--ds-dial-top, var(--ds-header-h)) var(--ds-dial-right, var(--ds-space-4)) auto auto;
    inline-size: min(26rem, calc(100% - var(--ds-space-8))); max-block-size: calc(100dvh - var(--ds-dial-top, var(--ds-header-h)) - var(--ds-space-4));
    border-block-end: 1px solid var(--sh-line); border-radius: var(--ds-radius-lg);
  }
  dialog.ds-dialsheet[data-placement="popover"][open] { animation-name: ds-dialsheet-fade; }
  dialog.ds-dialsheet[data-placement="popover"]::backdrop { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
  dialog.ds-dialsheet[data-placement="popover"] .ds-dialsheet__grip { display: none; }
  dialog.ds-dialsheet[data-placement="sheet"] {
    inset: 0; margin: auto; inline-size: min(28rem, calc(100% - var(--ds-space-6))); max-block-size: min(90dvh, 44rem);
    border-block-end: 1px solid var(--sh-line); border-radius: var(--ds-radius-lg);
  }
  dialog.ds-dialsheet[data-placement="sheet"][open] { animation-name: ds-dialsheet-fade; }
  dialog.ds-dialsheet[data-placement="sheet"] .ds-dialsheet__grip { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  dialog.ds-dialsheet[open] { animation: none; }
  .ds-dial__btn { transition: none; }
}
@media (forced-colors: active) {
  .ds-dial__btn { border: 1px solid ButtonText; }
  .ds-ring__seg.is-held { fill: Highlight; }
}
