/* DORES: three pains, their object cards, the three-service index, and the
 * service bar's visibility. Behaviour in dores.js.
 *
 * Two layouts share the same elements (each card lives in its index column):
 *   static  (no JS, reduced motion): sentences, then the index with its cards.
 *   live    (.is-live, pinned): layout A = cards floating around the
 *           sentences; .is-index = layout B, the index; .is-docked = folded
 *           into the service bar. .has-c1/2/3 = that card has landed.
 */

.dores .stage { display: flex; }
.dores-field {
  position: relative; flex: 1; min-height: 0; width: 100%; max-width: var(--maxw); margin: 0 auto;
  padding: var(--s9) var(--rail) var(--s8);
  display: flex; flex-direction: column; gap: var(--s8);
}

/* ---------- the three sentences ---------- */
.dores-field { --dores-fs: clamp(28px, min(4.2vw, 6vh), 56px); }
.dores-text {
  max-width: 14em; margin: 0 auto; display: flex; flex-direction: column; gap: .5em;
  font: 400 var(--dores-fs)/1.1 var(--serif); letter-spacing: -.015em; text-align: center; text-wrap: balance;
}
.dores-line b { font-weight: 400; white-space: nowrap; }   /* a key word ("10 pm") never breaks */
.dores .w { color: color-mix(in oklab, var(--faint), var(--ink) calc(var(--lit, 1) * 100%)); }
.dores .underline { position: relative; white-space: nowrap; }
html:not(.js) .dores .underline { text-decoration: underline 2px var(--signal); text-underline-offset: .16em; }
.dores .ul {
  position: absolute; left: -2%; top: 88%; width: 104%; height: .3em; overflow: visible; pointer-events: none;
  fill: none; stroke: var(--signal); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
  opacity: clamp(0, calc(var(--ul, 1) * 30), 1);
}
.dores .ul path { stroke-dasharray: 1 1; stroke-dashoffset: calc(1 - var(--ul, 1)); }

/* ---------- object cards (sizes in em of --card-fs) ---------- */
.dcard { font-size: var(--card-fs, 12px); width: 21em; max-width: 100%; text-align: left; line-height: 1.35; transform-origin: 0 0; }
.dcard p { margin: 0; }

/* 1 · iOS notification, dark material (atlas v1047) */
.dcard--note {
  padding: .85em 1.05em .95em; border-radius: 1.6em; color: #F2F2F7;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
  background: rgba(40, 42, 40, .82); -webkit-backdrop-filter: blur(24px) saturate(1.4); backdrop-filter: blur(24px) saturate(1.4);
  box-shadow: 0 1.6em 3.2em -1.2em rgba(0, 0, 0, .8), inset 0 0 0 1px rgba(255, 255, 255, .07);
}
.note-src { display: flex; flex-direction: column; }
.note-head { display: flex; align-items: center; gap: .55em; margin-bottom: .45em; font-size: .88em; letter-spacing: .03em; text-transform: uppercase; color: rgba(235, 235, 245, .55); }
.note-icon {
  flex: none; width: 1.75em; height: 1.75em; border-radius: .45em; background: #25D366 center / 66% no-repeat;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23fff' stroke-width='1.9' d='M12 3.1a8.9 8.9 0 0 0-7.7 13.4L3.1 20.9l4.5-1.2A8.9 8.9 0 1 0 12 3.1z'/%3E%3Cpath fill='%23fff' d='M9 7.5c.2-.4.4-.4.7-.4h.5c.2 0 .4 0 .6.4l.8 1.9c.1.2.1.4 0 .6l-.4.6c-.1.2-.2.3 0 .6.4.7 1 1.4 1.6 1.9.6.5 1.2.8 1.6 1 .2.1.4.1.5-.1l.7-.8c.2-.2.3-.2.6-.1l1.8.9c.3.1.4.2.4.4 0 .4-.1 1-.6 1.4-.4.4-1.2.8-2 .8-.9 0-2.4-.4-4-1.9-1.5-1.4-2.4-3-2.6-3.9-.3-1.1.1-2 .3-2.3z'/%3E%3C/svg%3E");
}
.note-time { margin-left: auto; letter-spacing: 0; text-transform: none; }
.note-title { font-size: 1.08em; font-weight: 600; }
.note-body { font-size: 1.08em; color: rgba(235, 235, 245, .86); }

/* 2 · a CRM record that never moved */
.dcard--crm {
  width: 22em; padding: 1em 1.15em 1.1em; border-radius: 1.05em; font-family: var(--sans);
  background: var(--surface); border: 1px solid var(--hair-2);
  box-shadow: 0 1.6em 3.2em -1.2em rgba(0, 0, 0, .8);
}
.crm-head { display: flex; align-items: center; gap: .75em; padding-bottom: .8em; border-bottom: 1px solid var(--hair); }
.crm-avatar { flex: none; width: 2.6em; height: 2.6em; border-radius: 50%; object-fit: cover; }
.crm-name { font-size: 1.12em; font-weight: 600; color: var(--ink); }
.crm-rows { display: grid; gap: .5em; padding-top: .8em; }
.crm-row { display: grid; grid-template-columns: 7.2em minmax(0, 1fr); gap: .6em; align-items: baseline; font-size: .95em; }
.crm-row .dk { color: var(--label); }
.crm-row .dv { color: var(--ink-2); }
.crm-row--status .dv {
  justify-self: start; display: inline-flex; align-items: center; gap: .45em; padding: .1em .65em .14em;
  border: 1px solid var(--hair-2); border-radius: 999px; color: var(--muted);
}
.crm-row--status .dv::before { content: ""; width: .45em; height: .45em; border-radius: 50%; background: var(--faint); }

/* 3 · Saturday's visit, with an empty CRM tray tucked under it */
.dcard--cal { font-family: var(--sans); }
.cal-event {
  position: relative; z-index: 1; padding: .85em 1em .9em 1.4em; border-radius: 1em;
  background: color-mix(in srgb, var(--info) 11%, var(--surface)); border: 1px solid color-mix(in srgb, var(--info) 30%, transparent);
  box-shadow: 0 1.4em 2.8em -1.2em rgba(0, 0, 0, .85);
}
.cal-event::before { content: ""; position: absolute; left: .62em; top: .85em; bottom: .85em; width: 3px; border-radius: 2px; background: var(--info); }
.cal-slot { display: flex; flex-direction: column; }
.cal-when { font-size: .88em; font-weight: 600; letter-spacing: .02em; color: var(--info); }
.cal-title { font-size: 1.15em; font-weight: 600; color: var(--ink); }
.cal-who { margin-top: .1em; padding-right: 3.6em; font-size: .92em; color: var(--ink-2); }
.cal-faces { position: absolute; right: .95em; top: .95em; display: flex; }
.cal-faces img { width: 2.1em; height: 2.1em; border-radius: 50%; object-fit: cover; border: 2px solid color-mix(in srgb, var(--info) 11%, var(--surface)); }
.cal-faces img + img { margin-left: -.6em; }
.cal-strip {
  position: relative; margin: -1em .75em 0; padding: 1.6em .95em .85em; display: grid; gap: .5em;
  border: 1px solid var(--hair-2); border-top: 0; border-radius: 0 0 .9em .9em; background: var(--raised);
  box-shadow: 0 1.4em 2.8em -1.2em rgba(0, 0, 0, .8);
}
.cal-field { display: grid; grid-template-columns: minmax(0, 1fr) 4.8em; gap: .6em; align-items: center; font-size: .9em; }
.cal-field .dk { color: var(--muted); }
.cal-field .dv { padding: .14em 0 .18em; text-align: center; border: 1px dashed var(--hair-2); border-radius: .45em; color: var(--label); }

/* ---------- the index (layout B; also the static end state) ---------- */
.dores-index {
  --card-fs: clamp(10px, .8vw, 11.5px);
  width: 100%; max-width: 1180px; margin: 0 auto;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: clamp(20px, 3.4vw, 48px); align-items: end;
}
.ix-col { display: flex; flex-direction: column; gap: var(--s5); min-width: 0; }
.ix-card-slot { display: flex; justify-content: flex-start; }
.ix-meta { position: relative; display: flex; flex-direction: column; gap: 10px; padding-top: var(--s4); }
.ix-meta::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--hair-2); transform-origin: 0 50%; }
.dores .ix-meta .svc-name { font-size: clamp(28px, 3.3vw, 48px); line-height: 1; }
.dores .ix-meta .svc-route { font-size: clamp(16px, 1.45vw, 21px); }

.dores-note { left: var(--rail); right: var(--rail); bottom: var(--s4); text-align: right; line-height: 1.5; }

/* phones: sizes follow the screen height so the whole index fits (360×740 up) */
@media (max-width: 699px) {
  .dores-field { --dores-fs: clamp(25px, 3.5vh, 30px); }
  .dores-index { --card-fs: clamp(8.5px, 1.13vh, 9.5px); grid-template-columns: minmax(0, 1fr); row-gap: clamp(14px, 2.6vh, 24px); max-width: 22rem; }
  .ix-col { gap: var(--s2); }
  .ix-meta { padding-top: var(--s2); gap: 4px; }
  .dores .ix-meta .svc-name { font-size: clamp(24px, 3.3vh, 28px); }
  .dores .ix-meta .svc-route { font-size: clamp(14px, 1.9vh, 16px); }
}

/* ================= live (pinned) ================= */
.dores.is-live .dores-field {
  height: 100%; padding: var(--s5) var(--rail) var(--s7);
  display: grid; grid-template: "stack" auto / minmax(0, 1fr); align-content: safe center;
}
.dores.is-live .dores-text,
.dores.is-live .dores-index { grid-area: stack; align-self: center; }

/* cards wait, hidden, until their beat; then slide in from --card-from */
.dores.is-live .dcard {
  visibility: hidden; opacity: 0; transform: var(--card-from, translateY(1.2em));
  transition: opacity .6s var(--ease), transform 1s var(--ease-expo);
}
.dores.is-live.has-c1 [data-card="1"],
.dores.is-live.has-c2 [data-card="2"],
.dores.is-live.has-c3 [data-card="3"] { visibility: visible; opacity: 1; transform: none; }

/* card 3: the empty CRM tray slides out from under the visit, then its fields */
.dores.is-live .cal-strip { opacity: 0; transform: translateY(-2.6em); transition: opacity .4s var(--ease) .3s, transform .8s var(--ease-expo) .3s; }
.dores.is-live.has-c3 .cal-strip { opacity: 1; transform: none; }
.dores.is-live .cal-field { opacity: 0; transition: opacity .5s var(--ease); }
.dores.is-live.has-c3 .cal-field { opacity: 1; }
.dores.is-live.has-c3 .cal-field:nth-child(1) { transition-delay: .6s; }
.dores.is-live.has-c3 .cal-field:nth-child(2) { transition-delay: .72s; }
.dores.is-live.has-c3 .cal-field:nth-child(3) { transition-delay: .84s; }

/* index text waits until .is-index, then the rule draws and the words rise */
.dores.is-live .ix-meta { visibility: hidden; }
.dores.is-live .ix-meta::before { transform: scaleX(0); transition: transform .9s var(--ease-expo); }
.dores.is-live .ix-meta > * { opacity: 0; transform: translateY(12px); transition: opacity .6s var(--ease), transform .8s var(--ease-expo); }
.dores.is-live.is-index .ix-meta { visibility: visible; }
.dores.is-live.is-index .ix-meta::before { transform: none; transition-delay: calc(.3s + var(--c) * .09s); }
.dores.is-live.is-index .ix-meta > * { opacity: 1; transform: none; transition-delay: calc(.42s + var(--c) * .09s + var(--j) * .06s); }
.ix-col:nth-child(1) { --c: 0; } .ix-col:nth-child(2) { --c: 1; } .ix-col:nth-child(3) { --c: 2; }
.ix-meta > :nth-child(1) { --j: 0; } .ix-meta > :nth-child(2) { --j: 1; } .ix-meta > :nth-child(3) { --j: 2; }

/* the sentences step back when the index arrives */
.dores.is-live .dores-text { transition: opacity .5s var(--ease), transform .7s var(--ease-expo), filter .5s var(--ease); }
.dores.is-live.is-index .dores-text { opacity: 0; transform: translateY(-16px); filter: blur(6px); pointer-events: none; }

/* folded into the bar: the columns' own animation fades them; then hide */
.dores.is-live.is-docked .dores-index,
.dores.is-live.is-docked .dores-note { opacity: 0; visibility: hidden; transition: opacity 0s .95s, visibility 0s .95s; }

/* layout A, wide: cards float left and right of the sentences, drifting with scroll */
@media (min-width: 1100px) {
  /* --gap-x: from the page centre to the cards, just past the longest line (~5.8em of the text) */
  .dores.is-live .dores-field { --gap-x: calc(var(--dores-fs) * 6.1); }
  .dores.is-live:not(.is-index) .dcard {
    --card-fs: clamp(11px, .98vw, 14px);
    position: absolute; translate: 0 calc((var(--s, 0) - var(--at)) * var(--drift));
  }
  .dores.is-live:not(.is-index) [data-card="1"] { top: 17%; left: calc(50% + var(--gap-x)); --at: .45; --drift: -24px; --card-from: translateY(-1.6em) scale(.96); }
  .dores.is-live:not(.is-index) [data-card="2"] { top: 41%; right: calc(50% + var(--gap-x)); --at: 1.15; --drift: -30px; --card-from: translateX(-2.6em); }
  .dores.is-live:not(.is-index) [data-card="3"] { top: 59%; left: calc(50% + var(--gap-x) + .6em); --at: 1.85; --drift: -36px; --card-from: translateX(2.6em); }
}

/* layout A, narrow: the sentences on top, the cards under them */
@media (max-width: 1099px) {
  .dores.is-live:not(.is-index) .dores-text { align-self: start; }
  .dores.is-live:not(.is-index) .dores-index { align-self: start; padding-top: calc(var(--text-h, 0px) + var(--s6)); }
  .dores.is-live:not(.is-index) .ix-meta { position: absolute; }
  .dores.is-live:not(.is-index) .dcard { --card-fs: 10.5px; }
}
@media (min-width: 700px) and (max-width: 1099px) {
  .dores.is-live:not(.is-index) .dores-index { grid-template-columns: repeat(3, auto); justify-content: center; align-items: start; column-gap: var(--s4); }
  .dores.is-live:not(.is-index) .dcard { --card-fs: clamp(9px, 1.3vw, 10.5px); }   /* three cards fit in one row */
  .dores.is-live:not(.is-index) [data-col="2"] { margin-top: var(--s6); }
  .dores.is-live:not(.is-index) [data-col="3"] { margin-top: var(--s3); }
}
@media (max-width: 699px) {
  .dores.is-live:not(.is-index) .dores-index { row-gap: clamp(6px, 1.2vh, 12px); max-width: none; padding-top: calc(var(--text-h, 0px) + clamp(16px, 3vh, 32px)); }
  .dores.is-live:not(.is-index) .dcard { --card-fs: clamp(9.5px, 1.3vh, 11px); }
  .dores.is-live:not(.is-index) [data-col="1"] .ix-card-slot,
  .dores.is-live:not(.is-index) [data-col="3"] .ix-card-slot { justify-content: flex-end; }
}

/* instant state changes (jumps, scrolling back): no transitions for one frame */
.dores.no-anim, .dores.no-anim * { transition: none !important; }

/* ================= service bar (markup in dores.html; base look in story.css) ================= */
/* hidden = not clickable or focusable, not just transparent */
.svc-bar { visibility: hidden; transition: opacity .5s var(--ease), transform .5s var(--ease), visibility 0s linear .5s; }
.svc-bar.is-on {
  visibility: visible;
  transition: opacity .5s var(--ease) var(--bar-delay, 0ms), transform .7s var(--ease-expo) var(--bar-delay, 0ms), visibility 0s linear 0s;
}
.svc-bar.no-anim, .svc-bar.no-anim * { transition: none !important; }
