/* ================================================================
   DTTASA Portal: THE OVERLAY SYSTEM
   ----------------------------------------------------------------
   AN EXACT PORT of "Overlay System.dc.html" from the Claude Design project
   (0bb3830f-415b-45ee-b74e-52897df39676), fetched 2026-07-28.

   THE DESIGN FILE IS THE CONTRACT. Every value below is copied from it, not
   approximated: the gradients, the radii, the animation curves and durations,
   the widths, the minimum touch heights. When this file and the design file
   disagree, this file is wrong.

   The VP's instruction, 2026-07-28: "all designs, CSS, overlays, layouts, text
   style and colour, must match the same with Claude design, the only thing we
   will change is the texts written in it and the workflow to use our internal
   data." So do NOT tune these numbers to taste. Change the text and the data
   source; leave the shell alone.

   ONE SHELL, EIGHT PERMITTED FORMS
   -------------------------------
   1 confirm, neutral        narrow, scrim closes
   2 confirm, destructive    narrow, red edge, typed unlock
   3 form                    sticky action bar, scrim LOCKED (unsaved work)
   4 detail, read only       wide, scrim closes, selectable text
   5 receipt                 narrow, gold, centred, reference as the hero
   6 choice with preview     wide, red edge, live colleague-facing preview
   7 drawer                  side panel, for a record rather than a decision
   8 blocking                no Escape, no scrim, no close, shown once

   THE RULES THAT HOLD ACROSS ALL EIGHT, quoted from the design:
     Escape closes anything that is not mid-submission.
     The scrim closes read-only overlays but NEVER a form with unsaved input.
     The primary action sits on the right.
     Destructive actions are never the default focus.
     No overlay opens another overlay on top of itself.
   js/dc-overlay.js enforces all five. They are behaviour, not decoration.
   ================================================================ */

/* ── Tokens, exactly as the design declares them ────────────────────── */
:root {
  --dc-gold:  #f0c832;
  --dc-red:   #ff4848;
  --dc-blue:  #5588ff;
  --dc-green: #4cd657;
  --dc-ink:   #f2f7ee;
  --dc-bg:    #0c1109;
  /* The card gradient. Two stops, 165deg. Not a flat panel. */
  --dc-card-a: #172213;
  --dc-card-b: #111a0e;
  --dc-line:   rgba(255,255,255,.20);
  --dc-line-soft: rgba(255,255,255,.14);
  --dc-body:   rgba(242,247,238,.88);
  --dc-muted:  rgba(242,247,238,.62);
  /* Every transition in the design uses this curve. */
  --dc-ease: cubic-bezier(.16,1,.3,1);
}

/* ── Animations, copied frame for frame ─────────────────────────────── */
@keyframes dcFadeIn { from { opacity:0 } to { opacity:1 } }
@keyframes dcMIn  { from { transform:translateY(18px) scale(.985); opacity:0 } to { transform:none; opacity:1 } }
@keyframes dcShIn { from { transform:translateY(100%) } to { transform:none } }
@keyframes dcDrIn { from { transform:translateX(28px); opacity:0 } to { transform:none; opacity:1 } }
@keyframes dcCvIn { from { transform:translateY(10px); opacity:0 } to { transform:none; opacity:1 } }
@keyframes dcRingIn { from { transform:scale(.8); opacity:0 } to { transform:none; opacity:1 } }
/* The receipt and blocking scan line. 200% background, so it sweeps. */
@keyframes dcScan { 0% { background-position:200% 0 } 100% { background-position:-200% 0 } }

/* ── The scrim ──────────────────────────────────────────────────────── */
.om-scrim {
  position:fixed; inset:0; z-index:800;
  background:rgba(0,0,0,.72);
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
  display:none; align-items:center; justify-content:center; padding:20px;
}
/* Shown by adding .show. NEVER put an inline display:none on the element: an
   inline style outranks any stylesheet rule that is not !important, so the
   class could not win and the trigger would read as dead. That exact bug cost
   a day on 2026-07-27, twice. */
.om-scrim.show { display:flex; animation:dcFadeIn .25s var(--dc-ease) both; }

/* The blocking form darkens further and blurs more, per the design. */
.om-scrim[data-kind="blocking"] {
  background:rgba(4,10,6,.86);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
}

/* ── The card ───────────────────────────────────────────────────────── */
.om-card {
  width:100%; max-width:min(600px, calc(100vw - 24px));
  max-height:calc(100vh - 40px); overflow-y:auto; overscroll-behavior:contain;
  padding:26px 24px; border-radius:16px;
  border:1px solid var(--dc-line);
  background:linear-gradient(165deg, var(--dc-card-a), var(--dc-card-b));
  position:relative;
  animation:dcMIn .32s var(--dc-ease) both;
  box-shadow:0 30px 70px -24px rgba(0,0,0,.75);
}
.om-card[data-w="wide"]   { max-width:min(720px, calc(100vw - 24px)); }
.om-card[data-w="narrow"] { max-width:min(480px, calc(100vw - 24px)); }
/* A destructive card is marked by a red LEFT EDGE, not a red border. */
.om-card[data-tone="destructive"] { border-left:3px solid var(--dc-red); }
.om-card[data-tone="gold"]        { border-color:rgba(240,200,50,.4); }
.om-card[data-center] { text-align:center; }

/* The grab handle exists only as a bottom sheet, so it is hidden by default. */
.om-grab { display:none; }

/* ── The drawer, form seven ─────────────────────────────────────────── */
.om-drawer-scrim { position:fixed; inset:0; z-index:790; background:rgba(0,0,0,.72);
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px); display:none; padding:0; }
.om-drawer-scrim.show { display:block; animation:dcFadeIn .25s var(--dc-ease) both; }
.om-drawer {
  position:fixed; top:0; right:0; bottom:0; z-index:800;
  width:min(560px, 94vw); overflow-y:auto; overscroll-behavior:contain;
  border-left:1px solid var(--dc-line);
  background:linear-gradient(165deg, var(--dc-card-a), var(--dc-card-b));
  box-shadow:-24px 0 60px -20px rgba(0,0,0,.7);
  display:none;
}
.om-drawer.show { display:block; animation:dcDrIn .38s var(--dc-ease) both; }
.om-drawer-head {
  position:sticky; top:0; z-index:4;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:14px 20px; border-bottom:1px solid var(--dc-line-soft);
  background:rgba(17,26,14,.92);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
}
.om-drawer-body { padding:20px; }

/* ── Typography, the three families the design uses ─────────────────── */
.om-scrim, .om-drawer { font-family:'DM Sans', system-ui, sans-serif; color:var(--dc-ink); }
.om-cin  { font-family:'Cinzel', serif; }
.om-mono { font-family:'IBM Plex Mono', ui-monospace, monospace; }

/* The eyebrow above every title: mono, 10px, 2px tracking, upper, coloured by
   the overlay's own tone. */
.om-eyebrow { font-family:'IBM Plex Mono', ui-monospace, monospace;
  font-size:10px; letter-spacing:2px; text-transform:uppercase; color:var(--dc-gold); }
.om-eyebrow[data-tone="destructive"] { color:var(--dc-red); }
.om-eyebrow[data-tone="info"]        { color:var(--dc-blue); }
.om-title { font-family:'Cinzel', serif; margin:9px 0 0; font-size:20px; line-height:1.28; font-weight:700; }
.om-card[data-w="wide"] .om-title { font-size:22px; line-height:1.26; }
.om-sub  { margin:11px 0 0; font-size:13.5px; line-height:1.6; color:var(--dc-body); }
.om-prose { margin:8px 0 0; max-width:66ch; font-size:14px; line-height:1.66;
  color:var(--dc-body); text-wrap:pretty; user-select:text; }

/* ── Buttons. 46px minimum, 12px radius, primary on the RIGHT. ──────── */
.om-acts { display:flex; gap:10px; margin-top:20px; }
.om-btn {
  min-height:46px; padding:0 18px; border-radius:12px;
  font-family:'DM Sans', sans-serif; font-size:14px; cursor:pointer;
  border:1px solid rgba(255,255,255,.21);
  background:rgba(255,255,255,.05); color:var(--dc-ink);
  transition:background .25s var(--dc-ease), border-color .25s var(--dc-ease),
             color .25s var(--dc-ease), transform .18s var(--dc-ease);
}
.om-btn:not(:disabled):active { transform:translateY(1px); }
.om-btn:disabled { opacity:.5; cursor:not-allowed; }
/* The primary. A gradient, dark ink on gold, heavier weight. */
.om-btn-primary {
  border-color:rgba(240,200,50,.34);
  background:linear-gradient(135deg, #f0c832, #f7d94e);
  color:var(--dc-bg); font-size:14.5px; font-weight:700;
}
.om-btn-danger {
  border-color:rgba(255,72,72,.5);
  background:rgba(255,72,72,.16); color:var(--dc-red); font-weight:700;
}
.om-btn-grow { flex:1 1 auto; }
.om-btn-hold { flex:0 0 auto; }
/* The close control, top right, 40px square. */
.om-x { position:absolute; top:16px; right:16px; width:40px; height:40px;
  border:1px solid rgba(255,255,255,.21); border-radius:10px;
  background:rgba(255,255,255,.05); color:var(--dc-ink); cursor:pointer; z-index:3; }
.om-x:hover { border-color:rgba(240,200,50,.34); color:var(--dc-gold); }
/* A card with a close button reserves room so the title never runs under it. */
.om-head-inset { padding-right:46px; }

/* ── Form three: the sticky action bar ──────────────────────────────── */
.om-sticky {
  position:sticky; bottom:-26px; margin:20px -24px -26px;
  padding:16px 24px calc(16px + env(safe-area-inset-bottom));
  border-top:1px solid var(--dc-line-soft);
  background:linear-gradient(180deg, rgba(23,34,19,.4), #111a0e 40%);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
}
.om-sticky .om-acts { margin-top:0; }
.om-sticky .om-btn { min-height:48px; }
.om-sticky .om-btn-primary { font-size:14.5px; }

/* ── Fields ─────────────────────────────────────────────────────────── */
.om-label { display:block; font-size:12.5px; line-height:1.5; white-space:normal; }
.om-field { width:100%; margin-top:8px; min-height:46px; padding:0 13px;
  border-radius:11px; border:1px solid rgba(255,255,255,.21);
  background:rgba(255,255,255,.05); color:var(--dc-ink); font-size:14px; outline:none; }
.om-field-ta { min-height:0; padding:12px 13px; border-radius:12px;
  font-family:'DM Sans', sans-serif; line-height:1.6; resize:vertical; }
.om-field::placeholder, .om-field-ta::placeholder { color:var(--dc-muted); }
.om-field:focus-visible, .om-btn:focus-visible, .om-x:focus-visible {
  outline:2px solid var(--dc-gold); outline-offset:2px; border-radius:8px; }
/* The typed-unlock field on a destructive confirm: wide letter spacing, and the
   border turns red only once the phrase matches. */
.om-field-phrase { font-family:'IBM Plex Mono', ui-monospace, monospace; letter-spacing:2px; }
.om-field-phrase[data-ok="1"] { border-color:rgba(255,72,72,.5); }
.om-count { margin-top:6px; font-family:'IBM Plex Mono', ui-monospace, monospace;
  font-size:11.5px; letter-spacing:1.2px; color:var(--dc-muted); }
.om-count[data-state="ok"]   { color:var(--dc-green); }
.om-count[data-state="near"] { color:var(--dc-gold); }

/* ── Radio and checkbox rows. 44px minimum, the real input is hidden. ── */
.om-opts { display:flex; flex-direction:column; gap:8px; margin-top:10px; }
.om-opt { display:flex; align-items:flex-start; gap:12px; min-height:44px;
  padding:12px 13px; border:1px solid rgba(255,255,255,.21); border-radius:11px;
  background:rgba(255,255,255,.03); cursor:pointer;
  font-size:13.5px; line-height:1.5; white-space:normal; color:var(--dc-body);
  transition:border-color .25s var(--dc-ease), background .25s var(--dc-ease); }
.om-opt[data-on="1"] { border-color:rgba(240,200,50,.45); background:rgba(212,175,55,.10); }
.om-dot { width:22px; height:22px; margin-top:1px; flex:0 0 auto; border-radius:50%;
  border:1.5px solid rgba(255,255,255,.4); display:flex; align-items:center; justify-content:center; }
.om-opt[data-on="1"] .om-dot { border-color:var(--dc-gold); }
.om-dot i { width:10px; height:10px; border-radius:50%; background:var(--dc-gold); display:none; }
.om-opt[data-on="1"] .om-dot i { display:block; }
.om-opt input { position:absolute; opacity:0; width:1px; height:1px; }
.om-check { width:26px; height:26px; margin-top:1px; flex:0 0 auto; border-radius:7px;
  border:1.5px solid rgba(255,255,255,.4); display:flex; align-items:center; justify-content:center; }
.om-optbox { padding:14px; border:1px solid rgba(255,255,255,.21); border-radius:12px;
  background:rgba(255,255,255,.03); margin-top:16px; }
.om-optbox .om-opt { border:0; background:none; padding:0; }

/* ── Notes and callouts ─────────────────────────────────────────────── */
.om-note { display:flex; align-items:flex-start; gap:11px; padding:14px 16px;
  border-radius:13px; font-size:13.5px; line-height:1.55; color:var(--dc-body);
  border:1px solid rgba(85,136,255,.4); background:rgba(85,136,255,.08); }
.om-note i { margin-top:3px; font-size:12px; color:var(--dc-blue); }
.om-note[data-tone="gold"] { border-color:rgba(240,200,50,.4); background:rgba(212,175,55,.10); }
.om-note[data-tone="gold"] i { color:var(--dc-gold); }
/* The live preview block on form six: what the colleague will actually read. */
.om-preview { margin-top:14px; padding:16px; border:1px solid rgba(85,136,255,.4);
  border-radius:13px; background:rgba(85,136,255,.08);
  animation:dcCvIn .3s var(--dc-ease) both; }
.om-preview-k { font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:9.5px;
  letter-spacing:1.8px; text-transform:uppercase; color:var(--dc-blue); }
.om-preview p { margin:11px 0 0; max-width:58ch; font-size:14px; line-height:1.7;
  color:var(--dc-body); text-wrap:pretty; }
.om-conseq { display:flex; flex-direction:column; gap:8px; margin-top:14px; }
.om-conseq-row { display:flex; gap:10px; font-size:13.5px; line-height:1.55; color:var(--dc-body); }
.om-conseq-row i { margin-top:3px; font-size:11px; }

/* ── Cells, the two-up detail grid ──────────────────────────────────── */
.om-g2 { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:12px; margin-top:18px; }
.om-cell { padding:12px 13px; border:1px solid var(--dc-line-soft); border-radius:12px; }
.om-cell-k { font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:9.5px;
  letter-spacing:1.8px; text-transform:uppercase; color:var(--dc-body); }
.om-cell-v { margin-top:5px; font-size:13.5px; }
.om-sec { margin-top:18px; }
.om-sec-k { font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:9.5px;
  letter-spacing:1.8px; text-transform:uppercase; color:var(--dc-gold); }

/* ── Form five: the receipt ─────────────────────────────────────────── */
.om-scan { position:absolute; left:0; right:0; top:0; height:1.5px;
  background:linear-gradient(90deg, transparent, var(--dc-gold), transparent);
  background-size:200% 100%; animation:dcScan 5.5s linear infinite; }
.om-ring { width:66px; height:66px; margin:6px auto 0; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  border:1.5px solid rgba(76,214,87,.5); background:rgba(76,214,87,.12);
  animation:dcRingIn .45s var(--dc-ease) .06s both; }
.om-ring i { font-size:24px; color:var(--dc-green); }
.om-ring[data-tone="gold"] { width:70px; height:70px;
  border-color:rgba(240,200,50,.5); background:rgba(212,175,55,.14); }
.om-ring[data-tone="gold"] i { font-size:26px; color:var(--dc-gold); }
/* The reference is the hero: 20px, 3.2px tracking, gold, in a bordered plate. */
.om-ref { display:inline-flex; flex-direction:column; align-items:center; gap:7px;
  margin-top:16px; padding:15px 20px; border:1px solid rgba(240,200,50,.45);
  border-radius:14px; background:rgba(212,175,55,.10);
  font-family:'IBM Plex Mono', ui-monospace, monospace; }
.om-ref-k { font-size:9.5px; letter-spacing:2.2px; text-transform:uppercase; color:var(--dc-body); }
.om-ref-v { font-size:20px; letter-spacing:3.2px; color:var(--dc-gold); }

/* ── The bottom sheet, at and below 640px ───────────────────────────── */
@media (max-width:640px) {
  .om-scrim.show { align-items:flex-end; padding:0; }
  .om-card {
    max-width:100% !important; border-radius:18px 18px 0 0; max-height:92vh;
    padding-bottom:calc(24px + env(safe-area-inset-bottom));
    animation:dcShIn .34s var(--dc-ease) both;
  }
  /* The grab handle appears only here. 44 by 4, centred. */
  .om-grab { display:block; width:44px; height:4px; margin:0 auto 16px;
    border-radius:999px; background:rgba(255,255,255,.28); }
  .om-g2 { grid-template-columns:1fr; }
  .om-acts { flex-direction:column-reverse; }
  .om-acts .om-btn { width:100%; }
  .om-drawer { width:100vw; }
  /* Every control reaches 44px under a thumb. */
  .om-btn, .om-x, .om-field { min-height:44px; }
  .om-x { position:static; margin:0 0 12px auto; }
  .om-head-inset { padding-right:0; }
}

/* ── The board header form ──────────────────────────────────────────────
   PORTED FROM THE BOARD DESIGNS, design-source/VMEM Board.dc.html and
   Head of HR Board.dc.html, which draw their overlay header as a row rather
   than using the absolute close button above:

       <div class="om-grab"></div>
       <div flex space-between>
         <div> eyebrow, h3 title </div>
         <button close 44x44 radius 11 />
       </div>
       <p blurb>

   Both forms are the same project. This one is what the two boards were drawn
   with, so it is what they use: the close button sits IN the row at 44px, the
   house touch minimum, instead of floating over the corner at 40px, and the
   blurb runs full width beneath rather than being indented past the button.
   `.om-head-inset` is not needed with this form and must not be combined with
   it, or the text is padded away from a button that is no longer there. */
.om-head { display:flex; align-items:flex-start; justify-content:space-between; gap:14px; }
.om-headtext { min-width:0; }
.om-head .om-x {
  position:static; flex:0 0 auto; width:44px; height:44px; border-radius:11px;
  border:1px solid rgba(255,255,255,.21); background:rgba(255,255,255,.05);
  color:#f2f7ee; cursor:pointer; margin:0;
}
.om-head .om-x i { font-size:13px; }
.om-head + .om-sub, .om-head + .om-prose { margin:11px 0 0; }
