/* ======================================================================
   3RD-I COMMAND · LIVE OPERATIONS
   The enterprise console. Sits high on the page, right under the trust
   rail, as the proof that a deployment is an operations product and not
   a bulk app licence.

   The organising rule, and the thing that keeps it on message: EVENTS ARE
   SHOWN BY PLACE AND STATUS, NEVER BY PERSON. Every feed row carries an
   explicit withheld-identity marker rather than a name, so the screen
   demonstrates the privacy position instead of quietly contradicting it.

   No map. A drawn fake map is the fastest way to make a product shot look
   generated, so location is carried by named areas and by real counts.

   Deliberately its own dark surface in both site themes: this is product
   chrome, not page chrome.
   ====================================================================== */

.depcon-sec { padding: clamp(56px, 7vw, 96px) 0 clamp(20px, 3vw, 34px); }
.depcon-head { max-width: 780px; margin-bottom: clamp(26px, 3.4vw, 40px); }
.depcon-head h2 { margin: 14px 0 0; }
.depcon-head .lede { margin: 16px 0 0; }

.depcon {
  --dc-ink: #070c1e;
  --dc-panel: rgba(255, 255, 255, .045);
  --dc-panel-2: rgba(255, 255, 255, .028);
  --dc-line: rgba(255, 255, 255, .10);
  --dc-line-soft: rgba(255, 255, 255, .065);
  --dc-text: #ffffff;
  --dc-muted: rgba(255, 255, 255, .60);
  --dc-faint: rgba(255, 255, 255, .40);
  --dc-pink: #f52d8c;
  --dc-violet: #8b5cf6;
  --dc-blue: #5678ff;
  --dc-green: #2fd39b;
  --dc-amber: #ffb020;
  --dc-red: #ff4d63;

  position: relative;
  overflow: hidden;
  border-radius: 22px;
  background: var(--dc-ink);
  border: 1px solid rgba(255, 255, 255, .09);
  box-shadow: 0 34px 78px rgba(10, 16, 40, .32);
  color: var(--dc-text);
  font-variant-numeric: tabular-nums;
}

.depcon::before,
.depcon::after { content: ""; position: absolute; border-radius: 50%; pointer-events: none; }
.depcon::before {
  right: -200px; top: -280px; width: 760px; height: 760px;
  background: radial-gradient(circle, rgba(245, 45, 140, .28), rgba(139, 92, 246, .13) 46%, transparent 70%);
}
.depcon::after {
  left: -260px; bottom: -340px; width: 700px; height: 700px;
  background: radial-gradient(circle, rgba(86, 120, 255, .22), transparent 68%);
}
.depcon-bg {
  position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(255, 255, 255, .042) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .042) 1px, transparent 1px);
  background-size: 54px 54px;
  -webkit-mask: radial-gradient(110% 90% at 25% 15%, #000 25%, transparent 78%);
          mask: radial-gradient(110% 90% at 25% 15%, #000 25%, transparent 78%);
}
.depcon > *:not(.depcon-bg) { position: relative; z-index: 2; }

/* ---------------------------------------------------------------- chrome */
.depcon-bar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 16px clamp(18px, 2.4vw, 26px);
  border-bottom: 1px solid var(--dc-line);
  background: rgba(255, 255, 255, .026);
}
.depcon-brand { display: flex; align-items: center; gap: 11px; }
.depcon-brand img { height: 24px; width: auto; display: block; }
.depcon-brand span {
  font-size: 13px; font-weight: 650; color: var(--dc-muted);
  padding-left: 11px; border-left: 1px solid var(--dc-line);
}
.depcon-bar-spacer { flex: 1 1 auto; }
.depcon-org { font-size: 12.5px; font-weight: 600; color: var(--dc-faint); }

/* Live chip. The dot is a status light on an operations screen, which is a
   real convention, so it stays a dot. No halo, no breathing animation. */
.dc-livechip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 14px; border-radius: 999px;
  border: 1px solid rgba(47, 211, 155, .30);
  background: rgba(47, 211, 155, .10);
  font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: #7ff0c6;
}
.dc-livechip i { width: 6px; height: 6px; border-radius: 50%; background: var(--dc-green); }
.dc-livechip small { font-weight: 600; letter-spacing: .02em; text-transform: none; color: rgba(255,255,255,.45); font-size: 11px; }

/* ------------------------------------------------------------------ body */
.depcon-body { padding: clamp(16px, 2.2vw, 24px); display: grid; gap: 14px; }

.depcon-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.dc-stat {
  border: 1px solid var(--dc-line-soft); border-radius: 14px;
  background: var(--dc-panel); padding: 14px 16px;
}
.dc-stat h4 {
  margin: 0; font-size: 10px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--dc-faint);
}
.dc-stat p { margin: 9px 0 0; font-size: clamp(24px, 2.6vw, 31px); font-weight: 700; letter-spacing: -.02em; line-height: 1; }
.dc-stat .u { font-size: 12px; font-weight: 600; color: var(--dc-muted); margin-left: 6px; letter-spacing: 0; }
.dc-stat--hot p { color: #ff8098; }

/* --------------------------------------------------------------- layout  */
.depcon-main { display: grid; grid-template-columns: 1.5fr 1fr; gap: 14px; align-items: start; }

.dc-panel {
  border: 1px solid var(--dc-line-soft); border-radius: 16px;
  background: var(--dc-panel); overflow: hidden;
}
.dc-panel-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px 18px; border-bottom: 1px solid var(--dc-line-soft);
}
.dc-panel-head h4 {
  margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--dc-faint);
}
.dc-panel-head .sp { flex: 1 1 auto; }
.dc-panel-head em {
  font-style: normal; font-size: 11px; font-weight: 600; color: var(--dc-faint);
}

/* ---- six hour activity strip, above the feed ---- */
.dc-strip { padding: 14px 18px 4px; }
.dc-strip svg { display: block; width: 100%; height: 42px; }
.dc-strip-ax {
  display: flex; justify-content: space-between; padding: 7px 0 0;
  font-size: 10px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--dc-faint);
}

/* ---- the event feed ---- */
.dc-feed { list-style: none; margin: 0; padding: 0; }
.dc-ev {
  display: grid;
  grid-template-columns: 3px minmax(0, 1fr) auto;
  gap: 0 15px;
  padding: 14px 18px;
  border-top: 1px solid var(--dc-line-soft);
}
.dc-ev:first-child { border-top: 0; }
.dc-ev-rail { grid-row: 1 / -1; border-radius: 999px; background: rgba(255, 255, 255, .18); }
.dc-ev--crit .dc-ev-rail { background: var(--dc-red); }
.dc-ev--elev .dc-ev-rail { background: var(--dc-amber); }
.dc-ev--info .dc-ev-rail { background: var(--dc-blue); }

.dc-ev-cat {
  font-size: 10px; font-weight: 700; letter-spacing: .15em; text-transform: uppercase;
  color: var(--dc-faint);
}
.dc-ev--crit .dc-ev-cat { color: #ff8098; }
.dc-ev--elev .dc-ev-cat { color: #ffc86a; }
.dc-ev-t { margin: 5px 0 0; font-size: 14.5px; font-weight: 650; letter-spacing: -.008em; }
.dc-ev-m { margin: 6px 0 0; display: flex; align-items: center; gap: 9px; flex-wrap: wrap; font-size: 12px; color: var(--dc-muted); }
.dc-ev-m .dot { width: 3px; height: 3px; border-radius: 50%; background: rgba(255,255,255,.3); }

/* The withheld-identity marker. Present on every row on purpose: the screen
   should look like it is actively refusing to name somebody, not like a feed
   that happens to have no names in it today. */
.dc-hid {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px 3px 7px; border-radius: 999px;
  border: 1px dashed rgba(255, 255, 255, .22);
  font-size: 10.5px; font-weight: 600; letter-spacing: .02em; color: var(--dc-faint);
}
.dc-hid svg { width: 11px; height: 11px; }

.dc-ev-side { grid-column: 3; grid-row: 1 / -1; align-self: center; text-align: right; }
.dc-ev-status {
  display: inline-block; padding: 6px 12px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: .03em; white-space: nowrap;
  border: 1px solid var(--dc-line); color: var(--dc-muted);
}
.dc-ev-status--live { border-color: rgba(255, 77, 99, .38); background: rgba(255, 77, 99, .12); color: #ff97a8; }
.dc-ev-status--work { border-color: rgba(255, 176, 32, .34); background: rgba(255, 176, 32, .10); color: #ffc86a; }
.dc-ev-status--done { border-color: rgba(47, 211, 155, .30); background: rgba(47, 211, 155, .09); color: #7ff0c6; }
.dc-ev-ago { display: block; margin-top: 7px; font-size: 11px; color: var(--dc-faint); }

/* ---- events by campus ---- */
.dc-areas { padding: 6px 18px 16px; }
.dc-area { padding: 12px 0; border-top: 1px solid var(--dc-line-soft); }
.dc-area:first-child { border-top: 0; }
.dc-area-top { display: flex; align-items: baseline; gap: 10px; }
.dc-area-n { font-size: 13.5px; font-weight: 650; }
.dc-area-c { margin-left: auto; font-size: 12px; font-weight: 600; color: var(--dc-muted); }
.dc-area-c b { color: var(--dc-text); font-weight: 700; }
.dc-area-bar { margin-top: 9px; height: 5px; border-radius: 999px; background: rgba(255, 255, 255, .08); overflow: hidden; }
.dc-area-bar i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--dc-pink), var(--dc-violet) 58%, var(--dc-blue)); }
.dc-area--quiet .dc-area-bar i { background: rgba(255, 255, 255, .26); }

/* ---- category mix ---- */
.dc-cats { padding: 4px 18px 18px; display: flex; flex-wrap: wrap; gap: 8px; }
.dc-cat {
  display: inline-flex; align-items: baseline; gap: 7px;
  padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--dc-line-soft); background: var(--dc-panel-2);
  font-size: 12px; color: var(--dc-muted);
}
.dc-cat b { color: var(--dc-text); font-weight: 700; }

/* ---- response rows ---- */
.dc-rows { margin: 0; padding: 6px 18px 16px; }
.dc-rows > div {
  display: flex; align-items: baseline; gap: 14px;
  padding: 11px 0; border-top: 1px solid var(--dc-line-soft);
}
.dc-rows > div:first-child { border-top: 0; }
.dc-rows dt { font-size: 12.5px; color: var(--dc-muted); }
.dc-rows dd { margin: 0 0 0 auto; font-size: 15px; font-weight: 700; letter-spacing: -.01em; }

/* --------------------------------------------------------- locked panel  */
.dc-locked {
  display: flex; align-items: center; gap: 20px;
  border: 1px dashed rgba(255, 255, 255, .17); border-radius: 16px;
  background: var(--dc-panel-2); padding: 20px 22px;
}
.dc-lock {
  flex: 0 0 auto; width: 38px; height: 38px; border-radius: 11px;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, .07); border: 1px solid var(--dc-line); color: var(--dc-muted);
}
.dc-lock svg { width: 17px; height: 17px; }
.dc-locked h4 { margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--dc-faint); }
.dc-locked-t { margin: 7px 0 0; font-size: 17px; font-weight: 700; letter-spacing: -.012em; }
.dc-locked-p { margin: 7px 0 0; font-size: 13px; line-height: 1.55; color: var(--dc-muted); max-width: 78ch; }

.depcon-foot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px clamp(18px, 2.4vw, 26px);
  border-top: 1px solid var(--dc-line);
  font-size: 12px; color: var(--dc-faint);
}
.depcon-foot b { color: var(--dc-muted); font-weight: 650; }

.depcon-cap { margin: 14px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--muted, #6f7892); text-align: center; }

/* --------------------------------------------------------------- mobile  */
@media (max-width: 1000px) {
  .depcon-main { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  .depcon-stats { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .depcon { border-radius: 18px; }
  .depcon-org { display: none; }
  .dc-stat { padding: 12px 13px; }
  /* The status pill moves under the event instead of fighting the title for
     width in a 3 column grid that no longer fits. */
  .dc-ev { grid-template-columns: 3px minmax(0, 1fr); padding: 13px 14px; }
  .dc-ev-side { grid-column: 2; grid-row: auto; text-align: left; margin-top: 10px; }
  .dc-ev-ago { display: inline; margin: 0 0 0 10px; }
  .dc-panel-head, .dc-strip, .dc-areas, .dc-cats, .dc-rows { padding-inline: 14px; }
  .dc-locked { flex-direction: column; align-items: flex-start; gap: 14px; padding: 18px; }
}

@media (prefers-reduced-motion: reduce) {
  .depcon * { animation: none !important; transition: none !important; }
}

/* ======================================================================
   MAP PANEL
   Real CARTO dark tiles (no labels, so no real institution is implied and
   our own area names are the only text on it), stitched once into
   command-basemap.webp. Attribution is required and sits bottom right.

   Events are drawn as an AREA BLOOM, not a pin. That is the whole point:
   the console places an event to a part of campus, it does not pinpoint a
   person. A pin would say the opposite of the panel underneath it.
   ====================================================================== */

.dc-map { position: relative; overflow: hidden; }
.dc-map-plate { position: relative; height: clamp(230px, 26vw, 330px); overflow: hidden; }
.dc-map-plate img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
}
/* Vignette so markers and the attribution stay legible over any tile. */
.dc-map-plate::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 40%, transparent 40%, rgba(7, 12, 30, .55) 100%),
    linear-gradient(180deg, rgba(7, 12, 30, .35), transparent 30%);
}

.dc-osm {
  position: absolute; right: 10px; bottom: 8px; z-index: 5;
  font-size: 9.5px; letter-spacing: .02em; color: rgba(255, 255, 255, .42);
}

/* ---- area markers ---- */
.dc-mk {
  position: absolute; z-index: 4; transform: translate(-50%, -50%);
  left: var(--x); top: var(--y);
  display: grid; place-items: center;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: inherit; font: inherit;
}
.dc-mk-area {
  grid-area: 1 / 1;
  width: 74px; height: 74px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .20);
  background: radial-gradient(circle, rgba(139, 92, 246, .34), rgba(139, 92, 246, .06) 62%, transparent 72%);
  transition: transform .22s ease, border-color .22s ease;
}
.dc-mk--crit .dc-mk-area { background: radial-gradient(circle, rgba(255, 77, 99, .40), rgba(255, 77, 99, .07) 62%, transparent 72%); border-color: rgba(255, 77, 99, .42); }
.dc-mk--elev .dc-mk-area { background: radial-gradient(circle, rgba(255, 176, 32, .34), rgba(255, 176, 32, .06) 62%, transparent 72%); border-color: rgba(255, 176, 32, .38); }
.dc-mk--info .dc-mk-area { background: radial-gradient(circle, rgba(86, 120, 255, .32), rgba(86, 120, 255, .06) 62%, transparent 72%); border-color: rgba(86, 120, 255, .36); }

.dc-mk-core { grid-area: 1 / 1; width: 9px; height: 9px; border-radius: 50%; background: #fff; }
.dc-mk--crit .dc-mk-core { background: #ff4d63; }
.dc-mk--elev .dc-mk-core { background: #ffb020; }
.dc-mk--info .dc-mk-core { background: #5678ff; }

.dc-mk-label {
  grid-area: 1 / 1; transform: translateY(52px); white-space: nowrap;
  padding: 4px 10px; border-radius: 999px;
  background: rgba(7, 12, 30, .82); border: 1px solid var(--dc-line);
  font-size: 10.5px; font-weight: 650; letter-spacing: .02em; color: var(--dc-muted);
  transition: color .22s ease, border-color .22s ease;
}

.dc-mk:hover .dc-mk-area,
.dc-mk:focus-visible .dc-mk-area { transform: scale(1.12); }
.dc-mk:focus-visible { outline: 2px solid #a07bff; outline-offset: 6px; border-radius: 50%; }

.dc-mk.is-sel .dc-mk-area { transform: scale(1.2); border-color: #fff; }
.dc-mk.is-sel .dc-mk-label { color: #fff; border-color: rgba(255, 255, 255, .42); }
.dc-mk.is-dim { opacity: .28; }

/* ---- campus filter chips ---- */
.dc-filters { display: flex; gap: 7px; flex-wrap: wrap; }
.dc-filter {
  padding: 6px 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--dc-line-soft); background: var(--dc-panel-2);
  font-size: 11.5px; font-weight: 600; color: var(--dc-muted);
  transition: color .18s ease, border-color .18s ease, background .18s ease;
}
.dc-filter:hover { color: #fff; border-color: var(--dc-line); }
.dc-filter[aria-pressed="true"] {
  color: #fff; border-color: transparent;
  background: linear-gradient(100deg, #f52d8c, #8b5cf6 58%, #5678ff);
}
.dc-filter:focus-visible { outline: 2px solid #a07bff; outline-offset: 2px; }

/* ---- feed rows become buttons ---- */
.dc-ev {
  width: 100%; text-align: left; background: none; color: inherit; font: inherit;
  cursor: pointer; transition: background .18s ease;
}
.dc-ev:hover { background: rgba(255, 255, 255, .03); }
.dc-ev:focus-visible { outline: 2px solid #a07bff; outline-offset: -2px; }
.dc-ev.is-sel { background: rgba(255, 255, 255, .055); }
.dc-ev.is-sel .dc-ev-t { color: #fff; }
.dc-ev[hidden] { display: none; }

.dc-empty { padding: 26px 18px; font-size: 13px; color: var(--dc-faint); }
.dc-empty[hidden] { display: none; }


/* ======================================================================
   PHONE PASS
   The console was built desktop-first and it showed: on a 390px screen the
   stat tiles ran to four fat boxes, the filter chips took two rows, the
   event rows cost ~200px each, and the map labels collided with each other
   and with the attribution. The whole section came to 2900px of scrolling.

   Rules applied here:
   - nothing decorative gets to cost a row
   - the map gets its own marker layout, because percentages tuned for a
     1100px plate put four labels on top of each other at 354px
   - the meta line stacks instead of wrapping, which kills the dangling
     separator dot that made rows look broken
   ====================================================================== */
@media (max-width: 640px) {
  .depcon:not(.is-framed) .depcon-body { padding: 12px; gap: 12px; }

  /* ---- status tiles ---- */
  .depcon-stats { gap: 8px; }
  .depcon:not(.is-framed) .dc-stat { padding: 11px 12px; border-radius: 12px; }
  .depcon:not(.is-framed) .dc-stat h4 { font-size: 9px; letter-spacing: .1em; }
  .depcon:not(.is-framed) .dc-stat p { margin-top: 6px; font-size: 22px; }
  .depcon:not(.is-framed) .dc-stat .u { font-size: 11px; margin-left: 4px; }

  /* ---- panel chrome ---- */
  .depcon:not(.is-framed) .dc-panel-head { padding: 12px 14px; gap: 8px; }
  .depcon:not(.is-framed) .dc-panel-head h4 { font-size: 10px; letter-spacing: .12em; }
  .depcon:not(.is-framed) .dc-panel-head em { font-size: 10.5px; }

  /* Chips go to one scrollable row rather than wrapping to two. Negative
     margins let them bleed to the panel edge so it reads as scrollable. */
  .depcon:not(.is-framed) .dc-filters {
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none; width: 100%;
    margin: 0 -14px; padding: 2px 14px 4px;
  }
  .depcon:not(.is-framed) .dc-filters::-webkit-scrollbar { display: none; }
  .depcon:not(.is-framed) .dc-filter { flex: 0 0 auto; padding: 5px 11px; font-size: 11px; }

  /* ---- map ---- */
  .depcon:not(.is-framed) .dc-map-plate { height: 268px; }
  .depcon:not(.is-framed) .dc-mk-area { width: 46px; height: 46px; }
  .depcon:not(.is-framed) .dc-mk-core { width: 7px; height: 7px; }
  .depcon:not(.is-framed) .dc-mk-label { transform: translateY(36px); font-size: 9.5px; padding: 3px 8px; }
  /* Positions retuned for a 354px plate. The desktop percentages stack three
     labels on one another at this width. */
  .depcon:not(.is-framed) [data-dc-mk="north"]     { --x: 64%; --y: 20%; }
  .depcon:not(.is-framed) [data-dc-mk="west"]      { --x: 19%; --y: 40%; }
  .depcon:not(.is-framed) [data-dc-mk="riverside"] { --x: 45%; --y: 63%; }
  .depcon:not(.is-framed) [data-dc-mk="south"]     { --x: 76%; --y: 82%; }
  /* South sits low enough that a label below it would fall off the plate. */
  .depcon:not(.is-framed) [data-dc-mk="south"] .dc-mk-label { transform: translateY(-34px); }
  /* Attribution moves off the south marker's corner. */
  .depcon:not(.is-framed) .dc-osm { left: 10px; right: auto; bottom: 6px; font-size: 9px; }

  .depcon:not(.is-framed) .dc-map .depcon-foot { padding: 11px 14px; gap: 4px; font-size: 11.5px; }

  /* ---- event feed ---- */
  .depcon:not(.is-framed) .dc-strip { padding: 12px 14px 2px; }
  .depcon:not(.is-framed) .dc-strip svg { height: 34px; }
  .depcon:not(.is-framed) .dc-ev { grid-template-columns: 3px minmax(0, 1fr); gap: 0 12px; padding: 12px 14px; }
  .depcon:not(.is-framed) .dc-ev-cat { font-size: 9px; letter-spacing: .12em; }
  .depcon:not(.is-framed) .dc-ev-t { margin-top: 4px; font-size: 14px; }
  /* block, not flex: a wrapped flex row left the separator dot dangling at
     the end of a line, which read as a rendering bug */
  .depcon:not(.is-framed) .dc-ev-m { display: block; margin-top: 5px; font-size: 11.5px; }
  .depcon:not(.is-framed) .dc-ev-m .dot { display: none; }
  .depcon:not(.is-framed) .dc-hid { margin-top: 6px; font-size: 10px; padding: 2px 8px 2px 6px; }
  .depcon:not(.is-framed) .dc-ev-side {
    grid-column: 2; grid-row: auto; margin-top: 9px; text-align: left;
    display: flex; align-items: center; gap: 10px;
  }
  .depcon:not(.is-framed) .dc-ev-status { padding: 4px 10px; font-size: 10.5px; }
  .depcon:not(.is-framed) .dc-ev-ago { display: inline; margin: 0; font-size: 10.5px; }

  /* ---- side panels ---- */
  .depcon:not(.is-framed) .dc-areas { padding: 4px 14px 12px; }
  .depcon:not(.is-framed) .dc-area { padding: 10px 0; }
  .depcon:not(.is-framed) .dc-area-n { font-size: 12.5px; }
  .depcon:not(.is-framed) .dc-area-c { font-size: 11.5px; }
  .depcon:not(.is-framed) .dc-cats { padding: 4px 14px 14px; gap: 6px; }
  .depcon:not(.is-framed) .dc-cat { padding: 6px 10px; font-size: 11.5px; }
  .depcon:not(.is-framed) .dc-rows { padding: 4px 14px 12px; }
  .depcon:not(.is-framed) .dc-rows > div { padding: 9px 0; }
  .depcon:not(.is-framed) .dc-rows dt { font-size: 11.5px; }
  .depcon:not(.is-framed) .dc-rows dd { font-size: 14px; }

  /* ---- locked panel + footer ---- */
  .depcon:not(.is-framed) .dc-locked { flex-direction: column; align-items: flex-start; gap: 12px; padding: 16px; }
  .depcon:not(.is-framed) .dc-locked-t { font-size: 15.5px; }
  .depcon:not(.is-framed) .dc-locked-p { font-size: 12.5px; }
  .depcon-bar { padding: 12px 14px; gap: 9px; }
  .depcon-brand span { font-size: 12px; }
  .depcon-foot { padding: 12px 14px; font-size: 11.5px; }
}

/* ======================================================================
   FRAMED WINDOW (phones and small tablets)
   Adam: on a phone this should read as one small horizontal screen showing
   the dashboard, not a 2500px column.

   So below 900px the console is laid out WIDE (map, feed and side panels in
   three columns, which is what an operations screen actually looks like),
   rendered at a fixed 1440px, and scaled down to fit the phone. You get the
   whole dashboard as a landscape window about 200px tall.

   Scale and stage height are set by command-console.js from the console's
   real measured height, so this cannot drift when the content changes. If
   JS does not run, the stacked phone pass above is still there.
   ====================================================================== */
.depcon-stage.is-framed-stage {
  position: relative;
  overflow: hidden;
  /* matches the console's own radius AFTER scaling, so the two curves nest
     exactly and the clip never bites into content */
  border-radius: calc(22px * var(--dc-s, 1));
}
.depcon.is-framed {
  position: absolute; top: 0; left: 0;
  width: var(--dc-w, 1600px);
  transform-origin: top left;
  transform: scale(var(--dc-s, 1));
  box-shadow: none;
  /* THE CROP. The stage was clipping with a fixed 20px radius while the
     console's own radius scaled down with everything else, so the much rounder
     mask sliced across the corners and ate the start of the footer line.
     Compensating the console's radius upward only moved the problem: a true
     20px corner is enormous next to a 10px-tall footer and swallowed the text
     anyway. The fix is the other direction. The console keeps its natural
     radius and scales like everything else, and the stage scales its radius to
     match, so the window is a faithful miniature and the curves nest. */
  border-radius: 22px;
}
/* transform: scale() does not change layout size, so a transformed console
   would leave the stage reporting a 1600px scroll width and you could pan
   into empty space when zoomed. This spacer is the element actually in flow:
   it is sized to the SCALED dimensions, so the stage's height and scroll
   extent both come out right. */
.dc-spacer { pointer-events: none; }

/* Three column operations layout, only inside the frame. */
.depcon.is-framed .depcon-body { grid-template-columns: 1.15fr 2fr; align-items: start; }
.depcon.is-framed .depcon-stats { grid-column: 1 / -1; }
.depcon.is-framed .dc-map { grid-column: 1; align-self: stretch; display: flex; flex-direction: column; }
.depcon.is-framed .dc-map-plate { flex: 1 1 auto; height: auto; min-height: 300px; }
.depcon.is-framed .depcon-main { grid-column: 2; }
.depcon.is-framed .dc-locked { grid-column: 1 / -1; }

/* The framed view is LOCKED. It is a picture of the screen, so nothing inside
   takes a touch: no panning, no zooming, no scroll trapped inside the window
   while the reader is trying to scroll the page. The console is fully
   interactive again above the breakpoint. */
.depcon-stage.is-framed-stage { overflow: hidden; touch-action: pan-y; }
.depcon-stage.is-framed-stage .depcon { pointer-events: none; user-select: none; }

/* The frame renders at 1600px but the VIEWPORT is still ~390px, so the
   viewport media queries above were collapsing the grids inside it and
   making the window twice as tall as it should be. Restore the wide grids
   explicitly; higher specificity wins regardless of source order. */
.depcon.is-framed .depcon-stats { grid-template-columns: repeat(4, 1fr); }
.depcon.is-framed .depcon-main { grid-template-columns: 1.55fr 1fr; }
.depcon.is-framed .dc-locked { flex-direction: row; align-items: center; }
.depcon.is-framed .dc-filters { flex-wrap: wrap; overflow: visible; margin: 0; padding: 0; width: auto; }
