/* ============================================================================
   screens/home.css - the dashboard
   ----------------------------------------------------------------------------
   Owns everything that only Home draws: the desktop stat strip, the module
   launcher, the two dashboard columns, and the whole mobile hero block (hero,
   snapshot, quick actions, app drawer, collapsed roster). Shared vocabulary -
   .card, .kcard, .av, .avstack, .bdg, .tag, .pill, .btn, .note, .empty, .toast
   and the mobile .pbody - comes from components.css and mobile.css and is never
   redeclared here.

   Four corrections from the audit are load-bearing in this file:

   1. All four stat tiles are the same component. The prototype's fourth tile
      reused .dstat and then fought it with two inline styles
      (background:transparent on the icon plate, font-size:19px on the value).
      There is no fourth-tile rule here, and none is needed.

   2. The mobile snapshot's three cells are structurally identical:
      .snap-v and .snap-av are the same fixed-height box, so the three captions
      line up because of the box model rather than because of an inline
      margin-top:8px on the odd one out.

   3. Nothing in here is a descendant selector that outranks a component class.
      The prototype's `.snap .s span` (0-2-1) beat .av--md and .av--gold and
      rendered the on-call avatar as a 10.5px translucent glyph. The caption is
      .snap-l, a class of its own, and .snap-av styles the WRAPPER only - no
      rule in this file touches an .av, a .bdg, a .btn or an .ic.

   4. Hover is only ever on something that actually does something: .dmod,
      a.mtile, .qact-item, .onshift and .dsec-go are all real <a href>. The
      inert blocks (.dstat, .snap-c, .rrow, and the disabled .mtile roadmap
      tiles) get no hover and no pointer cursor.

   Colours are tokens only. On the dark hero the prototype's white-alpha washes
   are replaced with the same ramp layout.css uses on the navy sidebar:
   --navy raised blocks, --navy-600 hairlines, --gray-300 / --gray-400 for
   de-emphasised text on dark.
   ============================================================================ */


/* ===========================================================================
   1. Desktop - page frame and section headers
   =========================================================================== */

/* position: relative anchors every .sr-only in here (an absolutely positioned
   box) to the dashboard. .content in layout.css is positioned too, for every
   screen, and that is what keeps such text inside the one desktop scroller;
   this rule came first (22 October 2026: at 1366x900 the module cards' counts
   stretched the locked window to a 2384px document) and stays because it
   costs nothing. */
.dhome{
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  min-width: 0;
  /* The dashboard is a reading width, not a stretch-to-fill grid. */
  max-width: 1180px;
}

/* A titled block: header row, then its content. Used by both views. */
.dsec{
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.dsec-t{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  margin-bottom: var(--s-3);
}

/* The heading carries its count pill inline, so the number and the label are
   one phrase for a screen reader ("Needs attention 4"). */
.dsec-t > h2{
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-width: 0;
}

/* The section's "go to the full screen" link. A real anchor, hence the hover. */
.dsec-go{
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  flex: none;
  font-family: var(--f-ui);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--gold-700);
  transition: color var(--t-fast);
}

/* --gold-600 text on the page ground measured 2.4:1; --gold-700 is the gold
   that reads as text (DESIGN.md 2). Hover steps to navy instead. */
.dsec-go:hover{
  color: var(--navy);
}


/* ===========================================================================
   1b. The attendance card

   One row: a glyph, two lines of text, an optional warning badge, and the one
   control that moves the day forward. Both panes draw the same element from
   the same /api/attendance/today payload.

   It is the only block on Home that is not a figure or a queue, so it is the
   only one that gets a real button. Everything else here is a link into the
   screen that owns the number.
   =========================================================================== */

.dattend-c{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4);
}

/* The state glyph. A plate rather than a bare icon, so the card reads as one
   object at a glance next to the KPI tiles below it. */
.dattend-ic{
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-sm);
  background: var(--gray-100);
  color: var(--gray-500);
}

/* The two states, in the same vocabulary the badges use elsewhere: grey for
   a day nobody has started, green for one that is checked in, which since 23
   October 2026 is a finished day. */
.dattend-c--awaited .dattend-ic{
  background: var(--gray-100);
  color: var(--navy);
}

.dattend-c--closed .dattend-ic{
  background: var(--green-100);
  color: var(--green-700);
}

.dattend-c--off .dattend-ic{
  background: var(--red-100);
  color: var(--red-700);
}

.dattend-b{
  flex: 1 1 180px;
  min-width: 0;
  line-height: 1.35;
}

.dattend-b b{
  display: block;
  font-size: 14px;
  font-weight: 600;
  color: var(--navy);
}

.dattend-d{
  display: block;
  font-size: 12px;
  color: var(--muted);
}

/* Inline, sized by its own words, and never stretched across the card. */
.dattend-late{
  flex: none;
}

.dattend-go{
  flex: none;
}

/* The skeleton row brings its own padding from ui.js, so the busy card does
   not add a second helping of its own. */
.dattend-c--busy{
  padding: var(--s-2) var(--s-3);
}


/* ===========================================================================
   2. KPI strip

   The tiles themselves are ui.statTile() from assets/js/ui.js - the app's one
   figure component - so this file owns the GRID and nothing inside a tile. The
   prototype's hand rolled .dstat is gone: it duplicated the component and then
   fought it with two inline styles.

   Every tile is an <a href> into the screen that owns the number, with the
   filter already in the query string, so the hover and the lift below are
   honest on all of them.
   =========================================================================== */

.dstats{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-4);
  min-width: 0;
}

/* The lift belongs to the tiles that really navigate. A tile whose destination
   this account may not open is rendered as a plain <div> and stays inert. */
.dstats a.ui-stat{
  transition:
    border-color var(--t-fast),
    box-shadow var(--t-fast),
    transform var(--t-fast);
}

.dstats a.ui-stat:hover{
  border-color: var(--gold);
  box-shadow: var(--sh-md);
  transform: translateY(var(--lift));
}

/* A long figure ("41%", "Rp 12,5jt") must wrap inside its tile rather than
   push the grid column wider than its track. */
.dstats .ui-stat-v{
  overflow-wrap: anywhere;
}


/* ===========================================================================
   3. Desktop - module launcher

   .dmod:hover was the only hover state in the whole prototype. It survives,
   and every other genuinely-interactive card in this file now has one too.
   =========================================================================== */

.dmods{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-3);
}

.dmod{
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: var(--s-5);
  cursor: pointer;
  transition:
    border-color var(--t-fast),
    box-shadow var(--t-fast),
    transform var(--t-fast);
}

.dmod:hover{
  border-color: var(--gold);
  box-shadow: var(--sh-md);
  transform: translateY(-2px);
}

.dmod-ic{
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  margin-bottom: var(--s-3);
  border-radius: var(--r);
  background: var(--navy-900);
  color: var(--gold);
}

/* The live row count the API ships with each module. Driven by the data, never
   hand typed, and absent entirely when the count is zero or unknown. */
.dmod-cnt{
  position: absolute;
  top: -7px;
  right: -9px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border: 2px solid var(--white);
  border-radius: 999px;
  background: var(--gold);
  color: var(--navy-900);
  font-family: var(--f-disp);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* An <h3>: the card title level, under the section's <h2>. */
.dmod-t{
  font-family: var(--f-disp);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--navy);
}

.dmod-b{
  display: block;
  margin-top: var(--s-1);
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted);
}


/* ===========================================================================
   4. Desktop - the two dashboard columns
   =========================================================================== */

.dcols{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-6);
  align-items: start;
}

/* The "Needs attention" stack. Replaces the prototype's inline
   `display:flex;flex-direction:column;gap:12px` wrapper. */
.dlist{
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}

/* A padded .card body. .card owns the surface; this owns the inside. */
.dcard{
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-5);
}

.droster{
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  min-width: 0;
}

/* One person's row. Inert - no cursor, no hover: the row does nothing, the
   section header's "Open schedule" link is what takes you somewhere. */
.rrow{
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-width: 0;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  background: var(--gray-50);
}

.rrow-m{
  flex: 1;
  min-width: 0;
  line-height: 1.3;
}

.rrow-m b{
  display: block;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--navy);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rrow-m span{
  display: block;
  font-size: 11.5px;
  color: var(--muted);
}

/* The signed in reader's own row. A hairline and a faint gold wash, so the row
   is findable at a glance without shouting over the six beside it. */
.rrow.is-selected{
  border: 1px solid var(--gold-300);
  background: var(--gold-a05);
}

/* "You", inline after the name rather than a second line. */
.rrow-you{
  margin-left: var(--s-2);
  padding: 1px var(--s-2);
  border-radius: 999px;
  background: var(--gold-100);
  color: var(--gold-700);
  font-family: var(--f-ui);
  font-size: 11px;
  font-weight: 700;
}

/* The handset beside whoever carries the on-call phone today. */
.rrow-call{
  display: flex;
  flex: none;
  color: var(--green);
}

.rrow-call .ic{
  width: 15px;
  height: 15px;
}


/* ===========================================================================
   5. Shift badge

   The prototype pasted the same ~150-character inline style five times to draw
   this, which is also why an "Off" or "On-call" person could not be shown: the
   only two literals written were the morning and afternoon ones. One class plus
   one modifier per shiftTypes id, so every roster state can be drawn.
   =========================================================================== */

/* NAME COLLISION FIX. schedule.css also declared a bare `.shift` - its grid-cell
   chip - at the same specificity, and index.html loads home.css first, so each
   file won for the properties it happened to declare and BOTH components broke:
   this badge inherited the chip's flex:1 and stretched across the roster row,
   while the chip inherited this badge's display:inline-flex and laid its two
   lines out side by side. The roster badge is therefore .rshift, scoped to its
   own .rrow, and schedule's chip is scoped to .sgrid. The `.rrow .shift` half
   of each selector list is a compatibility alias so the badge renders whether
   the markup emits the old name or the new one. */
.rshift,
.rrow .shift{
  display: inline-flex;
  align-items: center;
  flex: none;
  padding: var(--s-1) var(--s-3);
  border-radius: var(--r-sm);
  font-family: var(--f-ui);
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  background: var(--gray-100);
  color: var(--gray-600);
}

/* Morning */
.rshift--m,
.rrow .shift--m{ background: var(--gold);     color: var(--navy-900); }

/* Afternoon */
.rshift--a,
.rrow .shift--a{ background: var(--navy);     color: var(--white); }

/* On-call */
.rshift--c,
.rrow .shift--c{ background: var(--gold-100); color: var(--gold-700); }

/* Off - --gray-600 rather than --gray-500: the label is the only thing telling
   an Off badge apart from its neutral ground, and 2.9:1 did not carry it. */
.rshift--o,
.rrow .shift--o{ background: var(--gray-100); color: var(--gray-600); }

/* Flexible - the green of its color_token as a tint pair (5.4:1), so a part
   timer on flexible hours never reads as Off on the neutral ground above. */
.rshift--f,
.rrow .shift--f{ background: var(--green-100); color: var(--green-700); }


/* ===========================================================================
   6. Mobile - hero

   The gradient and the raised blocks inside it use the navy ramp, not the
   prototype's rgba(255,255,255,.06 / .08 / .09 / .10) washes.
   =========================================================================== */

.hero{
  flex: none;
  padding: var(--s-1) var(--s-5) var(--s-6);
  border-radius: 0 0 var(--r-xl) var(--r-xl);
  background: linear-gradient(180deg, var(--navy-900), var(--navy-800));
}

/* HERO MEMBAYAR SENDIRI JARAK DI BAWAH JAM PONSEL.

   Di dalam wadah Median, ponsel bernotch melaporkan safe area di atas. Jarak
   itu dibayar oleh KEPALA tiap layar, bukan oleh .main, supaya yang mewarnainya
   adalah elemen yang memang berada di bawah jam itu. Pada sembilan layar lain
   yang membayar adalah .phead yang berwarna putih; di sini hero yang berwarna
   navy. Penjelasan lengkap kenapa begitu ada di layout.css, di aturan .main.

   Hero ini memang dirancang menempel ke tepi atas: sudutnya hanya dibulatkan di
   bawah. Jadi ia tinggal menambahkan jaraknya ke padding atasnya sendiri, dan
   sapaan tetap berada di bawah notch.

   Pemilih anak langsung dipakai dengan sengaja: hanya Beranda yang menaruh
   .hero tepat di bawah .view-mobile, jadi aturan ini tidak bisa merembet ke
   layar lain. Di peramban tanpa notch --safe-t bernilai nol, dan baris di bawah
   tidak mengubah apa pun. */
.view-mobile > .hero{
  padding-top: calc(var(--s-1) + var(--safe-t));
}

.hero-top{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-2) 0 var(--s-4);
}

.hero-brand{
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-width: 0;
}

.hero-mark{
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: var(--r-sm);
  background: var(--gold);
  color: var(--navy-900);
  font-family: var(--f-disp);
  font-size: 19px;
  font-weight: 700;
  line-height: 1;
}

.hero-name{
  display: flex;
  align-items: baseline;
  gap: var(--s-1);
  min-width: 0;
  font-family: var(--f-disp);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--white);
}

.hero-name small{
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .16em;
  color: var(--gold);
}

.hero-actions{
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex: none;
}

/* The hero's icon button. position:relative is what the shared .dot--alert pip
   anchors to. It is an <a href="#/cases">, so the hover is honest. */
.hero-ib{
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: var(--r);
  background: var(--navy);
  color: var(--white);
  cursor: pointer;
  transition: background var(--t-fast);
}

.hero-ib:hover{
  background: var(--navy-600);
}

/* The mobile screen title. base.css paints h1 navy; the hero is dark. */
.greet{
  font-family: var(--f-disp);
  font-size: 23px;
  font-weight: 600;
  letter-spacing: -.01em;
  line-height: 1.2;
  color: var(--white);
}

.greet-sub{
  margin-top: var(--s-1);
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--gray-400);
}


/* ===========================================================================
   7. Mobile - the three-cell snapshot

   FIX: every cell holds exactly two boxes - a value carrier of a fixed height,
   then a caption. .snap-v (a number) and .snap-av (an avatar) are the SAME box,
   so all three captions sit at the same offset structurally. The prototype's
   third cell had no <b> at all and its caption was pushed down with an inline
   margin-top:8px that only approximated the alignment.

   FIX: there is no `.snap .s span` here. That selector scored 0-2-1 and beat
   both .av--md and .av--gold, so the on-call avatar rendered as a 10.5px
   translucent-white glyph on gold instead of 13px navy. Nothing below reaches
   inside .snap-av.
   =========================================================================== */

.snap{
  display: flex;
  align-items: stretch;
  margin-top: var(--s-4);
  padding: var(--s-4) var(--s-2);
  border: 1px solid var(--navy-600);
  border-radius: var(--r-lg);
  background: var(--navy);
}

.snap-c{
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  padding: 0 var(--s-1);
}

.snap-c + .snap-c::before{
  content: "";
  position: absolute;
  top: var(--s-1);
  bottom: var(--s-1);
  left: 0;
  width: 1px;
  background: var(--navy-600);
}

/* The shared box. Its height is the avatar's height, so the number cell and the
   avatar cell measure the same. */
.snap-v,
.snap-av{
  display: flex;
  align-items: center;
  justify-content: center;
  height: 36px;
}

.snap-v{
  font-family: var(--f-disp);
  font-size: 24px;
  font-weight: 600;
  line-height: 1;
  color: var(--gold);
}

.snap-l{
  font-size: 10.5px;
  line-height: 1.3;
  text-align: center;
  color: var(--gray-400);
}


/* ===========================================================================
   8. Mobile - quick actions
   =========================================================================== */

.qact{
  display: flex;
  gap: var(--s-2);
  margin-top: var(--s-5);
}

.qact-item{
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-1) 0;
  border-radius: var(--r);
  cursor: pointer;
}

.qact-ic{
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: var(--r-lg);
  background: var(--navy);
  color: var(--gold);
  transition: background var(--t-fast);
}

.qact-item:hover .qact-ic{
  background: var(--navy-600);
}

.qact-l{
  font-style: normal;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
  color: var(--gray-300);
}


/* ===========================================================================
   9. Mobile - the eight-tile app drawer

   Four live tiles are <a href="#/id">. The three roadmap tiles AND Settings are
   <button disabled aria-disabled="true" title="…">: not focusable, announced as
   disabled, and visibly inert. The prototype gave Settings no SOON badge even
   though it was every bit as dead as the other three.
   =========================================================================== */

.mgrid{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-5) var(--s-1);
}

.mtile{
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  min-width: 0;
  padding: var(--s-1) 0;
  border-radius: var(--r);
}

.mtile-ic{
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 58px;
  height: 58px;
  border-radius: var(--r-lg);
  background: var(--gray-100);
  color: var(--navy);
  transition: background var(--t-fast), color var(--t-fast);
}

.mtile-l{
  font-style: normal;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
  color: var(--navy);
}

/* A tile carrying a live count is highlighted - driven by the data, not by an
   inline style on one hand-picked tile. */
.mtile--alert .mtile-ic{
  background: var(--gold-100);
  color: var(--gold-600);
}

/* Only the anchor tiles are tappable. `a.mtile:hover .mtile-ic` outranks
   .mtile--alert, so the highlighted Cases tile still reacts. */
a.mtile{
  cursor: pointer;
}

a.mtile:hover .mtile-ic{
  background: var(--gold-100);
  color: var(--gold-600);
}

.mtile-cnt{
  position: absolute;
  top: -6px;
  right: -6px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 19px;
  height: 19px;
  padding: 0 5px;
  border: 2px solid var(--gray-50);
  border-radius: 999px;
  background: var(--gold);
  color: var(--navy-900);
  font-family: var(--f-disp);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.mtile-soon{
  position: absolute;
  top: -7px;
  right: -10px;
  padding: 2px 6px;
  border: 1.5px solid var(--gray-50);
  border-radius: var(--r-sm);
  background: var(--gray-100);
  color: var(--gray-600);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
}

.mtile:disabled,
.mtile.is-disabled{
  cursor: not-allowed;
}

.mtile:disabled .mtile-ic,
.mtile.is-disabled .mtile-ic{
  border: 1px solid var(--gray-200);
  background: var(--gray-50);
  color: var(--gray-400);
}

.mtile:disabled .mtile-l,
.mtile.is-disabled .mtile-l{
  color: var(--gray-400);
}


/* ===========================================================================
   10. Mobile - collapsed on-shift roster

   `<a class="card onshift" href="#/schedule">`: .card supplies the surface,
   this supplies the layout and - because it really is a link - a hover.
   =========================================================================== */

.onshift{
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-width: 0;
  padding: var(--s-3) var(--s-4);
  cursor: pointer;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}

.onshift:hover{
  border-color: var(--gold);
  box-shadow: var(--sh-md);
}

.onshift-m{
  flex: 1;
  min-width: 0;
  line-height: 1.3;
}

.onshift-m b{
  display: block;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--navy);
}

.onshift-m span{
  display: block;
  font-size: 11.5px;
  color: var(--muted);
}

.onshift-go{
  display: flex;
  flex: none;
  color: var(--gray-400);
}


/* ============================================================================
   11. <= 1180px - the dashboard grids reflow 4 -> 2 columns.

   This is the app's other breakpoint (layout.css owns the 860px shell switch).
   It lives here because it only ever moves these three grids.
   ============================================================================ */

@media (max-width: 1180px){

  .dstats{
    grid-template-columns: repeat(2, 1fr);
  }

  .dmods{
    grid-template-columns: repeat(2, 1fr);
  }

  .dcols{
    grid-template-columns: 1fr;
  }

}


/* ---------------------------------------------------------------------------
   Touch floor for the row links, phones only.

   Measured on 11 September 2026 at 320, 390 and 430px: .dcase-t came out 16px
   tall, .dsec-go 17px, .dfrow--go 17px. Each of them is a real destination, not
   decoration, and each sat well under the 44px floor the rest of the app keeps.

   Room is added around the text rather than to the text, so the dashboard keeps
   its density on the desktop side of the breakpoint.
   --------------------------------------------------------------------------- */
@media (max-width: 860px){
  .dcase-t,
  .dsec-go,
  .dfrow--go{
    display: flex;
    align-items: center;
    min-height: 44px;
  }
}


/* ---------------------------------------------------------------------------
   The attendance control on a phone.

   It is the reason most of the team opens the app, and beside two lines of
   text it comes out about 90px wide, sitting on the far side of the card from
   the thumb that has to reach it. Its own row, the full width, and 48px tall:
   a control that is pressed standing up in a lobby, often one handed.

   The warning badge keeps its own size. It is a label, and a label stretched
   across a card reads as a control that does nothing.
   --------------------------------------------------------------------------- */
@media (max-width: 860px){
  .dattend-go{
    flex: 1 0 100%;
    min-height: 48px;
  }
}


/* The two round buttons in the dark hero, the bell and the account. 38px is
   under the floor the rest of the app keeps, and on the hero they sit close to
   the screen edge where a thumb is least accurate. */
@media (max-width: 860px){
  .hero-ib{
    width: 44px;
    height: 44px;
  }
}


/* ---------------------------------------------------------------------------
   The narrowest phones, under 380px.

   Two columns of stat tiles still fit on a 390px screen and read well there.
   At 320px they do not: labels like "Warranty ending" and "Leave to approve"
   break across two lines, the sentence under the number runs to four, and the
   two tiles in a row end up different heights, so the grid looks ragged.
   One column is the honest answer at that width.
   --------------------------------------------------------------------------- */
@media (max-width: 380px){
  .dstats,
  .dmods{
    grid-template-columns: 1fr;
  }
}

/* ------------------------------------------------------------------ *
 * Recent activity (.dfeed, .dfrow) and the load error card (.derr)
 *
 * Markup from home.js activityRow() and the error block. Until 28 September
 * 2026 no rule styled them, so an activity row read as one run of text
 * ("Checked in at 08:59 IY Irene Yunita.2h ago").
 * ------------------------------------------------------------------ */
.dfeed{
  list-style: none;
  margin: 0;
  padding: var(--s-2) var(--s-3);
  display: flex;
  flex-direction: column;
}
.dfeed > li + li{ border-top: 1px solid var(--gray-100); }

.dfrow{
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  min-width: 0;
  padding: var(--s-3) var(--s-2);
  color: inherit;
  text-decoration: none;
}
.dfrow--go{ border-radius: var(--r-sm); transition: background var(--t-fast); }
.dfrow--go:hover{ background: var(--gold-a05); }

.dfrow-ic{
  flex: none;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--gray-100);
  color: var(--gray-600);
}
.dfrow-b{ flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dfrow-t{ font-weight: 600; line-height: 1.4; color: var(--navy-900); overflow-wrap: anywhere; }
.dfrow-m{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--gray-600);
}
.dfrow-dot{ color: var(--gray-400); }
.dfrow-go{ flex: none; align-self: center; color: var(--gray-400); }

.derr{
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-left: 4px solid var(--red);
}
.derr--strip{ border-left-color: var(--gold); }
.derr-ic{ flex: none; color: var(--red-700); }
.derr--strip .derr-ic{ color: var(--gold-700); }
.derr-b{ flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.derr-t{ color: var(--navy-900); }
.derr-m{ font-size: 13px; color: var(--gray-600); overflow-wrap: anywhere; }
