/* ============================================================================
   DTTASA Portal — responsive.css
   ----------------------------------------------------------------------------
   Centralised mobile-compatibility rules and shared interaction patterns.
   Loaded from every page via the standard `<link>` block alongside
   `utilities.css` and `style-shim.css`.

   Anything that should look the SAME across pages goes here:
     • Mobile breakpoints + touch-target sizing rules
     • Shared interaction patterns (chat rows, modal sheets, etc.)
     • Pointer/hover capability gates
     • Safe-area insets for iOS standalone PWA

   Anything PAGE-SPECIFIC stays in the page's own `css/<page>.css`.
   Anything PER-ELEMENT-INLINE that was extracted by tools/extract-inline-styles
   lives in `css/style-shim.css` (auto-generated, do not hand-edit).

   Rule of thumb: if the same selector would be useful on three or more pages,
   it belongs here.
   ============================================================================ */


/* ──────────────────────────────────────────────────────────────────────────
   Touch-target minimums
   ──────────────────────────────────────────────────────────────────────────
   CLAUDE.md mandate: every tappable element must have a ≥44×44 hit area
   on touch devices. Use `.touch-target` as a wrapper class on small icons
   that don't naturally meet that size — invisible padding extends the tap
   zone without growing the visible footprint. */
.touch-target{
  min-width:44px;min-height:44px;
  display:inline-flex;align-items:center;justify-content:center;
}


/* ──────────────────────────────────────────────────────────────────────────
   Chat message row, delete control, and read-receipt meta line
   ──────────────────────────────────────────────────────────────────────────
   Used by the dashboard chat on index.html. Defined here (not in
   `css/index.css`) so the same look applies to any other future page that
   reuses these classes (e.g. an HR-Ops chat side-panel, a comms inbox). */
.chat-msg-row{padding:3px 0;}
.chat-msg-meta{
  display:flex;align-items:center;gap:4px;
  font-size:9px;color:var(--t3);margin-top:3px;
}
.chat-msg-meta .fa-check,
.chat-msg-meta .fa-check-double{font-size:10px;}
.chat-msg-del{
  /* Visually small (icon ~11px) but the button itself is a 44×44 touch
     target via padding — meets the touch-target rule above. The
     transparent excess area is invisible. */
  appearance:none;background:transparent;border:0;cursor:pointer;
  color:var(--red);opacity:.55;
  width:44px;height:44px;padding:0;margin:-12px -10px -12px 2px;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:11px;transition:opacity .15s,color .15s;
}
.chat-msg-del:hover,.chat-msg-del:focus{opacity:1;color:var(--red);outline:none;}

/* Desktop with a real pointer: keep the original "appears on hover" feel so
   the chat doesn't look cluttered. Mobile / touch always shows it. */
@media (hover:hover) and (pointer:fine){
  .chat-msg-del{opacity:0;transition:opacity .15s;}
  .chat-msg-row:hover .chat-msg-del{opacity:.7;}
  .chat-msg-row:hover .chat-msg-del:hover{opacity:1;}
}


/* ──────────────────────────────────────────────────────────────────────────
   Safe-area insets — iOS standalone PWA
   ──────────────────────────────────────────────────────────────────────────
   Pages can opt-in by adding `.safe-bottom` to a sticky footer or
   `.safe-top` to a sticky header. Avoids the iOS home-indicator overlap. */
.safe-bottom{padding-bottom:max(12px,env(safe-area-inset-bottom));}
.safe-top{padding-top:max(0px,env(safe-area-inset-top));}


/* ──────────────────────────────────────────────────────────────────────────
   Mobile readability — minimum legible font sizes on phones
   ──────────────────────────────────────────────────────────────────────────
   Users reported text was straining their eyes on mobile (2026-05-18).
   The CLAUDE.md tokens (13/14/15/18 px) are reasonable on desktop but feel
   tight on a 320–540 px phone screen. We bump common small-text patterns
   up by 1–2 px below the 540 px breakpoint, and force inputs to 16 px so
   iOS Safari stops auto-zooming when a field is focused.

   Targeted bumps only — we don't blanket-resize the document, which would
   knock card layouts off their grids. Selectors aim at the small-text
   classes used across pages.

   Cascade: these rules carry `!important` because the inline shim classes
   (`.s-…`) generated by `tools/extract-inline-styles.mjs` ALSO carry
   `!important` (they had to, to preserve the original inline-style
   priority). Without `!important` here the per-element shim wins and our
   mobile-readability bumps silently fail. */

@media (max-width:540px){
  /* Base body text — bump conservatively. */
  body{font-size:14px !important;}

  /* Form inputs — 16 px is the iOS Safari threshold below which Safari
     auto-zooms when the field receives focus. That zoom is jarring on a
     PWA where the viewport is meta-locked. 16 px on textareas + inputs
     stops it cold. */
  input, textarea, select, button{font-size:16px !important;}

  /* Common small-text utility / pattern classes used across pages. */
  .u-fs9-13, .u-fs10, .u-fs11{font-size:13px !important;}
  .u-fs12, .u-fs13{font-size:14px !important;}

  /* Labels, captions, helper text. */
  label, .label, .mlbl, .form-label, .field-label,
  .form-hint, .form-help, .helper-text, .helper, small{font-size:13px !important;}

  /* Table cells and key/value pair rows. */
  td, th, .dtbl td, .dtbl th, .cell, .row-meta{font-size:13px !important;}

  /* Badges and pill chips can stay slightly smaller but not tiny. */
  .pip, .sbadge, .pill, .chip, .tag{font-size:12px !important;}

  /* Section / panel headings. */
  .sec-head, .panel-title, .card-title{font-size:16px !important;}
  h1{font-size:22px !important;}
  h2{font-size:19px !important;}
  h3{font-size:17px !important;}
  h4, h5, h6{font-size:15px !important;}

  /* Chat message bubbles + meta line (centralised above) — keep readable. */
  .chat-msg-meta{font-size:11px !important;}
  .chat-msg-meta .fa-check,
  .chat-msg-meta .fa-check-double{font-size:12px !important;}
}

@media (max-width:400px){
  /* Slightly more aggressive on very small phones. */
  body{font-size:14.5px !important;}
  h1{font-size:21px !important;}
  h2{font-size:18px !important;}
}


/* ──────────────────────────────────────────────────────────────────────────
   Apply Credit to Cell — published shift action (SA / Head of HR only)
   ──────────────────────────────────────────────────────────────────────────
   Small gold "hand holding dollar" icon in the corner of every published
   timed-shift cell. Opens a modal that draws N hours from the user's
   banked credit and shortens the published shift by N hours. */
.cell-apply-credit-btn{
  position:absolute;top:4px;right:4px;z-index:3;
  width:22px;height:22px;border-radius:6px;
  appearance:none;cursor:pointer;
  background:rgba(212,175,55,.12);border:1px solid rgba(212,175,55,.35);
  color:var(--gold,#f0c832);
  display:inline-flex;align-items:center;justify-content:center;
  font-size:11px;transition:.15s;opacity:.0;
}
.alloc-cell{position:relative;}
.alloc-cell:hover .cell-apply-credit-btn,
.cell-apply-credit-btn:focus{opacity:1;}
.cell-apply-credit-btn:hover{background:rgba(212,175,55,.28);border-color:var(--gold,#f0c832);}
@media (hover:none){
  /* Touch devices — always-visible at lower opacity so admins can tap. */
  .cell-apply-credit-btn{opacity:.85;width:26px;height:26px;font-size:12px;}
}

.cellc-modal-overlay{
  position:fixed;inset:0;z-index:99999;
  background:rgba(10,14,8,.85);backdrop-filter:blur(10px);
  display:flex;align-items:center;justify-content:center;padding:24px;
  font-family:'DM Sans',sans-serif;
}
.cellc-modal-card{
  background:#172213;border:1px solid var(--gold,#f0c832);border-radius:14px;
  max-width:540px;width:100%;color:var(--text,#f2f7ee);
  box-shadow:0 24px 60px rgba(0,0,0,.5);
}
.cellc-modal-head{padding:22px 24px 14px;border-bottom:1px solid var(--border,rgba(255,255,255,.21));}
.cellc-modal-title{font-family:'Cinzel',serif;font-size:15px;letter-spacing:2.5px;color:var(--gold,#f0c832);margin-bottom:8px;}
.cellc-modal-sub{font-size:13px;color:var(--t2,rgba(242,247,238,.88));line-height:1.55;}
.cellc-modal-body{padding:18px 24px;}
.cellc-row{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;font-size:13px;}
.cellc-row span:first-child{color:var(--t3,rgba(242,247,238,.62));}
.cellc-mono{font-family:'IBM Plex Mono',monospace;color:var(--text,#f2f7ee);}
.cellc-credit{color:var(--green,#4cd657);font-weight:700;}
.cellc-dim{color:var(--t3,rgba(242,247,238,.62));font-weight:400;}
.cellc-input-row{margin:14px 0 8px;display:flex;flex-direction:column;gap:6px;}
.cellc-input-row label{font-size:12px;color:var(--t2,rgba(242,247,238,.88));font-weight:600;}
.cellc-input-row input{
  appearance:none;background:rgba(255,255,255,.08);border:1px solid var(--border,rgba(255,255,255,.21));
  border-radius:8px;padding:10px 12px;font-size:16px;color:var(--text,#f2f7ee);
  font-family:'IBM Plex Mono',monospace;
}
.cellc-input-row input:focus{outline:none;border-color:var(--gold,#f0c832);background:rgba(212,175,55,.08);}
.cellc-preview{
  background:rgba(212,175,55,.08);border:1px solid rgba(212,175,55,.3);
  border-radius:8px;padding:10px 12px;font-size:13px;line-height:1.5;
  color:var(--text,#f2f7ee);margin-bottom:14px;
}
.cellc-label{display:block;font-size:12px;color:var(--t2,rgba(242,247,238,.88));font-weight:600;margin-bottom:6px;}
.cellc-modal-body textarea{
  width:100%;background:rgba(255,255,255,.06);border:1px solid var(--border,rgba(255,255,255,.21));
  border-radius:8px;padding:10px 12px;font-size:14px;color:var(--text,#f2f7ee);
  font-family:'DM Sans',sans-serif;resize:vertical;min-height:60px;
  box-sizing:border-box;
}
.cellc-modal-body textarea:focus{outline:none;border-color:var(--gold,#f0c832);}
.cellc-err{color:var(--red,#ff4848);font-size:12px;margin-top:8px;min-height:18px;}
.cellc-modal-actions{
  padding:14px 24px 20px;border-top:1px solid var(--border,rgba(255,255,255,.21));
  display:flex;gap:12px;justify-content:flex-end;
}
.cellc-modal-actions .btn{min-width:120px;}

/* ──────────────────────────────────────────────────────────────────────────
   Required-field error shake — reusable highlight for inputs/textareas
   that fail validation. The shake makes the warning unmissable; the red
   border + tinted background is applied inline so it stays visible after
   the animation ends (until the user starts typing again). */
.field-error-shake{
  animation: dttasa-shake-x 0.45s cubic-bezier(.36,.07,.19,.97);
}
@keyframes dttasa-shake-x {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}

/* Cell-credit modal error text — keep loud + bold so the warning isn't
   easily missed under the textarea. */
.cellc-err{font-weight:600;}

/* ──────────────────────────────────────────────────────────────────────────
   HR-view back button — visible only when public referee/HR-detail forms
   open in Capacitor PWA (window.open(_blank) routes to the same view in
   iOS WebView, leaving the HR user stranded without a navigation chrome).
   The button is positioned top-left, gold-on-dark, easy to thumb-tap. */
.rf-hr-back-btn{
  position:fixed;top:max(16px,env(safe-area-inset-top));left:16px;z-index:9999;
  display:inline-flex;align-items:center;gap:8px;
  padding:10px 16px;border-radius:10px;
  background:rgba(212,175,55,.18);color:var(--gold,#f0c832);
  text-decoration:none;font-weight:700;font-size:13px;
  border:1px solid rgba(212,175,55,.4);
  box-shadow:0 6px 18px rgba(0,0,0,.35);
  font-family:'DM Sans',sans-serif;
  transition:.15s;
}
.rf-hr-back-btn:hover,.rf-hr-back-btn:focus{
  background:rgba(212,175,55,.32);
  outline:none;
  transform:translateY(-1px);
}
@media (max-width:540px){
  .rf-hr-back-btn{padding:9px 12px;font-size:12px;}
  .rf-hr-back-btn span{display:none;}
}

/* ──────────────────────────────────────────────────────────────────────────
   HR-decision radio rows — applicant-ref-details-form
   The labels have class `.s-rpubrhw` (hashed from Phase 4 extractor).
   When a radio inside is checked, highlight the parent label so the user
   has clear visual feedback for their selection. Uses :has() — supported
   on all modern Chromium / Safari / Firefox versions on the target users'
   devices (iOS Safari ≥ 15.4). */
label.s-rpubrhw:has(input[type="radio"]:checked){
  background:rgba(212,175,55,.10) !important;
  border-color:rgba(212,175,55,.55) !important;
  box-shadow:0 0 0 2px rgba(212,175,55,.18), inset 0 1px 0 rgba(255,255,255,.06) !important;
}
label.s-rpubrhw:has(input[type="radio"]:checked) strong{
  text-shadow:0 0 8px rgba(212,175,55,.25);
}
label.s-rpubrhw:has(input[type="radio"][value="approve"]:checked){
  background:rgba(34,197,94,.12) !important;
  border-color:rgba(34,197,94,.5) !important;
  box-shadow:0 0 0 2px rgba(34,197,94,.18) !important;
}
label.s-rpubrhw:has(input[type="radio"][value="reject"]:checked){
  background:rgba(239,68,68,.12) !important;
  border-color:rgba(239,68,68,.5) !important;
  box-shadow:0 0 0 2px rgba(239,68,68,.18) !important;
}
label.s-rpubrhw:has(input[type="radio"][value="more-info"]:checked){
  background:rgba(245,158,11,.12) !important;
  border-color:rgba(245,158,11,.5) !important;
  box-shadow:0 0 0 2px rgba(245,158,11,.18) !important;
}
label.s-rpubrhw{transition:background .2s, border-color .2s, box-shadow .2s;}

/* "Credit already applied" status pill — replaces the Apply Credit button
   on a draft-week row once a credit application is on file for this week.
   Non-interactive (no button), green-tinted to communicate "done". */
.rec-applied-status{
  display:inline-flex;align-items:center;gap:6px;
  font-size:11px;font-weight:600;
  background:rgba(76,214,87,.10);
  border:1px solid rgba(76,214,87,.32);
  color:var(--green,#4cd657);
  padding:5px 10px;border-radius:6px;
}
.rec-applied-status i{font-size:11px;}
@media (max-width:540px){
  .cellc-modal-card{max-width:calc(100vw - 32px);}
  .cellc-modal-actions{flex-direction:column-reverse;}
  .cellc-modal-actions .btn{width:100%;}
}

/* ════════════════════════════════════════════════════════════════
   Centralised mobile button sizing.
   ════════════════════════════════════════════════════════════════
   Per-page CSS had a habit of bricking every action button to
   width:100% + min-height:44px on small viewports, which produced
   the "really big buttons" feel — three actions per card became
   three full-width 50px-tall blocks.

   Standardise: on ≤640px, action buttons flex-fit their content,
   wrap to a second line only when they overflow, and have a
   comfortable but not oversized min-height. Pages can still force
   width:100% on specific containers (modal CTAs, hero buttons)
   where it's the right call.
   ════════════════════════════════════════════════════════════════ */
@media (max-width:640px){
  /* Default touch sizing — 38px clears Apple HIG 44pt minimum once
     padding is added. Use !important sparingly: only on the size to
     beat per-page 44px overrides that drove the oversized feel.
     Padding + font-size also tighten because the base portal-wide
     `.btn` is a chunky pill (padding:13px 26px; letter-spacing:2px)
     that reads too large on iPhone. */
  body .btn:not(.btn-xs):not(.btn-sm){
    min-height:38px;
    padding:8px 16px!important;
    font-size:11px!important;
    letter-spacing:1.2px!important;
  }
  body .btn-sm{
    min-height:32px;
    padding:6px 12px!important;
    font-size:10.5px!important;
    letter-spacing:.9px!important;
  }
  body .btn-xs{
    min-height:26px;
    padding:4px 9px!important;
    font-size:10px!important;
    letter-spacing:.6px!important;
  }
  /* Section header utility classes use `.sec-lbl` for the title and a
     hashed flex-row container. Tighten the title font on mobile so the
     "ADD NOTE" gold button doesn't look bigger than the heading. */
  body .sec-lbl{font-size:13px;letter-spacing:1.2px;}

  /* Generic action-row pattern across the portal: any flex/grid row
     of buttons that previously forced full-width stacking gets a
     side-by-side flex-wrap behaviour instead. Buttons grow but never
     stretch to the full row alone. */
  body .card-actions:not(.btn-full-row),
  body .action-row:not(.btn-full-row),
  body .row-actions:not(.btn-full-row),
  body .actions:not(.btn-full-row){
    display:flex!important;
    flex-wrap:wrap;
    gap:6px;
  }
  body .card-actions:not(.btn-full-row) .btn,
  body .action-row:not(.btn-full-row)  .btn,
  body .row-actions:not(.btn-full-row) .btn,
  body .actions:not(.btn-full-row)     .btn{
    flex:1 1 auto;
    min-width:fit-content;
    width:auto;
    justify-content:center;
  }
}

/* ════════════════════════════════════════════════════════════════
   Centralised notification-panel overflow guard.
   Header bells across the portal (#notif-panel on IT board, .sys-
   notif-panel on dashboards, etc.) are absolute-positioned to the
   bell button itself. The bell typically sits mid-header on mobile,
   so a 310-320px panel extending in either direction overflows the
   viewport — half the panel is off-screen and the user can't read
   it. Switch to `position:fixed` on small viewports so the panel
   docks to the viewport edge with a viewport-wide max-width.
   ════════════════════════════════════════════════════════════════ */
@media (max-width:820px){
  body .notif-panel,
  body #notif-panel,
  body .sys-notif-panel,
  body #sys-notif-panel{
    position:fixed!important;
    top:calc(var(--hdh, 66px) + 8px)!important;
    right:10px!important;
    left:10px!important;
    width:auto!important;
    max-width:calc(100vw - 20px)!important;
    max-height:calc(100vh - var(--hdh, 66px) - 24px)!important;
    overflow-y:auto;
  }
}
