/* BIMQP Employee Portal — design system derived from the BIMQP logo:
   coral-red wordmark, dark navy-black accent shapes, bold geometric type. */

:root {
  --brand: #E8463B;
  --brand-dark: #C93A30;
  --brand-light: #F4695F;
  --ink: #14202E;
  --muted: #5B6A82;
  --muted-light: #8A96A8;
  --bg: #F5F6F8;
  --bg-red-wash: #FDECEA;
  --bg-green-wash: #E9F9EF;
  --line: #E7E9EE;
  --white: #FFFFFF;
  --success: #1F9D55;
  --success-ink: #14532D;
  --radius: 10px;
  --radius-sm: 6px;
  --shadow: 0 1px 3px rgba(20, 32, 46, 0.06), 0 6px 20px rgba(20, 32, 46, 0.06);
}

* { box-sizing: border-box; }

html { -webkit-font-smoothing: antialiased; }

body {
  margin: 0;
  font-family: 'Poppins', 'Segoe UI', Arial, Helvetica, sans-serif;
  background: var(--bg);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.55;
}

/* ---------- Top bar ---------- */
/* White, matching the logo's native background — its dark navy accent shape
   would blend into a dark bar, so the bar stays light with a red underline
   instead of inverting to the brand's dark tone. */
.topbar {
  background: var(--white);
  border-bottom: 3px solid var(--brand);
  box-shadow: 0 1px 2px rgba(20,32,46,0.05);
}
.topbar-inner {
  max-width: 1080px;
  margin: 0 auto;
  padding: 10px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
}
.brand img { height: 34px; display: block; }
.brand-text {
  color: var(--ink);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.2px;
  border-left: 1.5px solid var(--line);
  padding-left: 10px;
}

.nav {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}
.nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 500;
  transition: color 0.15s ease;
}
.nav a:hover { color: var(--brand); }
.nav-user {
  color: var(--ink);
  font-weight: 600;
  font-size: 13.5px;
}

/* ---------- Avatar ---------- */
.avatar {
  border-radius: 50%;
  object-fit: cover;
  display: inline-block;
  flex-shrink: 0;
}
.avatar-initials {
  background: var(--brand);
  color: #fff;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  letter-spacing: 0.3px;
}

/* ---------- Nav profile dropdown ---------- */
.nav-profile { position: relative; }
.nav-profile-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-left: 14px;
  border: none;
  border-left: 1px solid var(--line);
  background: none;
  cursor: pointer;
  font-family: inherit;
}
.nav-profile-trigger:hover .nav-user { color: var(--brand); }
.nav-profile-caret { color: var(--muted-light); flex-shrink: 0; }
.nav-profile-menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: 240px;
  background: var(--white);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  border: 1px solid rgba(20,32,46,0.06);
  overflow: hidden;
  z-index: 50;
}
.nav-profile-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  border-bottom: 1px solid var(--line);
}
.nav-profile-name { font-weight: 700; font-size: 14px; color: var(--ink); }
.nav-profile-role { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.nav-profile-links { padding: 6px; border-bottom: 1px solid var(--line); }
.nav-profile-links:last-child { border-bottom: none; }
.nav-profile-links a {
  display: block;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 500;
  text-decoration: none;
  transition: background 0.15s ease;
}
.nav-profile-links a:hover { background: var(--bg); color: var(--brand); }
/* Log Out moved from a plain GET link to a CSRF-protected POST form (a bare
   <a href="logout.php"> could be forged cross-site to force-end a session),
   so it needs its own reset to keep looking identical to the other
   View Profile/Change Password links beside it. */
.nav-profile-logout-btn {
  display: block;
  width: 100%;
  padding: 9px 10px;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 500;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease;
}
.nav-profile-logout-btn:hover { background: var(--bg); color: var(--brand); }

/* ---------- Page shell ---------- */
.page {
  max-width: 1080px;
  margin: 32px auto;
  padding: 0 24px;
}
/* Wide variant for data-heavy pages (e.g. the admin Dashboard's 11-column
   table) that shouldn't be squeezed into the standard content width. */
.page-wide { max-width: 1600px; }

.card {
  background: var(--white);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 28px 32px;
  margin-bottom: 22px;
  border: 1px solid rgba(20,32,46,0.04);
}
.card-narrow { max-width: 440px; margin-left: auto; margin-right: auto; }

h1 { margin: 0 0 14px; font-size: 21px; font-weight: 700; letter-spacing: -0.2px; }
h2 { margin: 0 0 12px; font-size: 16px; font-weight: 600; }
h3 { margin: 18px 0 8px; font-size: 13.5px; font-weight: 600; color: var(--ink); }
.muted { color: var(--muted); font-size: 13.5px; }
.meta { font-size: 13px; margin-top: 16px; color: var(--muted); }
/* :not(.btn) — otherwise this red link color beats .btn-primary's white
   text (equal specificity, this rule comes later), which on a red-background
   button like reset-password.php's "Sign in" meant red text on a red
   button: invisible. Plain text links in .meta still get the red treatment;
   an actual button dropped in here keeps its own button styling. */
.meta a:not(.btn) { color: var(--brand); font-weight: 500; text-decoration: none; }
.meta a:not(.btn):hover { text-decoration: underline; }

/* ---------- Forms ---------- */
form label {
  display: block;
  margin-bottom: 15px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
form input[type=text], form input[type=email], form input[type=password],
form input[type=number], form input[type=file], form select, form input:not([type]), form textarea {
  display: block;
  width: 100%;
  padding: 10px 12px;
  margin-top: 6px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-family: inherit;
  color: var(--ink);
  background: var(--white);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
form textarea { resize: vertical; }
form input:focus, form select:focus, form textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--bg-red-wash);
}
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 24px;
}
.inline-form { display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap; margin-bottom: 20px; }
.inline-form label { margin-bottom: 0; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  padding: 10px 22px;
  border-radius: var(--radius-sm);
  border: 1.5px solid var(--line);
  background: var(--white);
  color: var(--ink);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: all 0.15s ease;
}
.btn:hover { border-color: var(--muted-light); background: var(--bg); }
.btn-primary {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
  box-shadow: 0 2px 8px rgba(232, 70, 59, 0.28);
}
.btn-primary:hover { background: var(--brand-dark); border-color: var(--brand-dark); }
.btn-success {
  background: var(--success);
  border-color: var(--success);
  color: #fff;
  box-shadow: 0 2px 8px rgba(31, 157, 85, 0.28);
}
.btn-success:hover { background: var(--success-ink); border-color: var(--success-ink); }
/* Thin vertical rule between button groups in a filter bar — keeps a
   distinct action (like Export CSV) from reading as part of the filter's
   own submit button just because they sit next to each other. */
.btn-divider { display: inline-block; width: 1px; height: 22px; background: var(--line); margin: 0 4px; vertical-align: middle; }
.link-btn {
  background: none;
  border: none;
  color: var(--brand);
  text-decoration: underline;
  cursor: pointer;
  padding: 0;
  font-size: 13px;
  font-family: inherit;
  font-weight: 500;
}
.link-btn:hover { color: var(--brand-dark); }

/* ---------- Alerts ---------- */
.alert { padding: 13px 18px; border-radius: var(--radius-sm); margin-bottom: 18px; font-size: 13.5px; }
.alert-error { background: var(--bg-red-wash); border-left: 3px solid var(--brand); color: #7A1F16; }
.alert-success { background: var(--bg-green-wash); border-left: 3px solid var(--success); color: var(--success-ink); }

/* ---------- Delete confirmation modal (bimqpConfirmDelete, _lib/layout.php) ----------
   Replaces the old native prompt("Type DELETE"). The overlay fades in and
   the card scales up from 0.96 — both purely CSS-driven off the
   .confirm-overlay-in class the JS adds a frame after insertion (so the
   transition actually has a starting state to animate from). */
.confirm-overlay {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(20, 32, 46, 0.001);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  opacity: 0;
  transition: opacity 0.15s ease, background 0.15s ease;
}
.confirm-overlay-in { opacity: 1; background: rgba(20, 32, 46, 0.45); }
.confirm-modal {
  background: var(--white);
  border-radius: var(--radius);
  box-shadow: var(--shadow), 0 20px 50px rgba(20, 32, 46, 0.25);
  padding: 28px 28px 24px;
  width: 100%; max-width: 380px;
  text-align: center;
  transform: scale(0.94) translateY(6px);
  transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.confirm-overlay-in .confirm-modal { transform: scale(1) translateY(0); }
.confirm-modal-icon {
  width: 44px; height: 44px; margin: 0 auto 14px;
  border-radius: 50%;
  background: var(--bg-red-wash);
  color: var(--brand);
  font-family: Georgia, serif;
  font-weight: 700; font-size: 22px;
  display: flex; align-items: center; justify-content: center;
}
.confirm-modal-message { margin: 0 0 18px; font-size: 14.5px; color: var(--ink); line-height: 1.5; }
.confirm-modal-label {
  display: block; text-align: left;
  font-size: 11.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px;
  color: var(--muted); margin-bottom: 18px;
}
.confirm-modal-input {
  display: block; width: 100%; margin-top: 7px;
  padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  font-size: 14px; font-family: inherit; text-align: center; letter-spacing: 1px;
  color: var(--ink); background: var(--white);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.confirm-modal-input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--bg-red-wash); }
.confirm-modal-actions { display: flex; gap: 10px; }
.confirm-modal-actions .btn { flex: 1; width: auto; }
.confirm-modal-delete:disabled, .confirm-modal-submit:disabled { opacity: 0.4; cursor: not-allowed; box-shadow: none; }
.confirm-modal-icon-ok { background: var(--bg-green-wash); color: var(--success); }
/* Accept/Reject uses a textarea instead of the delete modal's one-line
   input — remarks-modal widens the card slightly to give it more room. */
.remarks-modal { max-width: 420px; }
.remarks-modal .confirm-modal-message { font-weight: 700; font-size: 16px; }
.confirm-modal-textarea {
  display: block; width: 100%; margin-top: 7px;
  padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  font-size: 13.5px; font-family: inherit; line-height: 1.5; letter-spacing: normal; text-align: left;
  color: var(--ink); background: var(--white);
  resize: vertical;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.confirm-modal-textarea:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--bg-red-wash); }

/* ---------- Photo crop modal (admin/employees.php) ----------
   Same overlay/card chrome as the confirm modals, widened to fit the crop
   stage. The canvas is the actual crop output (drawn at final size) —
   border-radius just clips it into a circle for preview, matching how
   .avatar is displayed everywhere else; the saved file itself stays a
   plain square JPEG. */
.crop-modal { max-width: 380px; }
.crop-stage {
  position: relative;
  width: 260px; height: 260px;
  margin: 4px auto 14px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--bg);
  box-shadow: 0 0 0 3px var(--white), 0 0 0 4px var(--line);
  cursor: grab;
  touch-action: none;
}
.crop-stage:active { cursor: grabbing; }
.crop-stage canvas { display: block; }
.crop-zoom-label {
  display: block; text-align: left;
  font-size: 11.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px;
  color: var(--muted); margin-bottom: 18px;
}
.crop-zoom { width: 100%; margin-top: 8px; }

/* ---------- Status boxes ---------- */
.status-box { border-radius: var(--radius); padding: 20px 22px; margin: 16px 0; }
.status-box.status-pending { background: var(--bg-red-wash); border-left: 3px solid var(--brand); }
.status-box.status-ok { background: var(--bg-green-wash); border-left: 3px solid var(--success); }

/* ---------- Instructions box ----------
   Reworked from a heavy dark "notice board" block into a light,
   collapsible card matching the rest of the portal's white-card language —
   the dark block visually outweighed the actual status/action card below
   it. Placement also moved (dashboard.php) so the employee's own status
   and action buttons come first; this reference material comes after,
   collapsed by default via bimqpInitInstructionsToggle() (_lib/layout.php)
   remembering the open/closed state per-browser in localStorage. */
.instructions-box {
  background: var(--white);
  border: 1px solid var(--line);
  border-left: 3px solid var(--brand);
  border-radius: var(--radius);
  margin: 18px 0;
  overflow: hidden;
}
.instructions-toggle {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%;
  padding: 16px 22px;
  background: none; border: none; cursor: pointer;
  font-family: inherit; text-align: left;
}
.instructions-toggle h2 {
  margin: 0;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-weight: 700;
  color: var(--ink);
}
.instructions-caret {
  color: var(--muted);
  transition: transform 0.18s ease;
  flex-shrink: 0;
  margin-left: 12px;
}
.instructions-box.is-open .instructions-caret { transform: rotate(180deg); }
.instructions-body {
  padding: 0 22px 22px;
}
.instructions-box:not(.is-open) .instructions-body { display: none; }
/* Generous line-height since this is meant to hold a numbered sequence of
   steps (typed as separate lines in Settings), not a single short blurb —
   each point needs room to read as its own line, not a cramped paragraph. */
.instructions-box p { color: var(--ink); font-size: 13.5px; line-height: 1.85; margin: 0; }

/* ---------- Badges ---------- */
.badge { display: inline-block; padding: 3px 11px; border-radius: 20px; font-size: 11.5px; font-weight: 700; letter-spacing: 0.2px; text-transform: uppercase; }
.badge-pending { background: var(--bg-red-wash); color: #B3392F; }
.badge-ok { background: var(--bg-green-wash); color: var(--success-ink); }
.badge-neutral { background: var(--bg); color: var(--muted); border: 1px solid var(--line); }

/* ---------- Signed-in role badge (profile dropdown) ---------- */
.nav-profile-role-badge { margin-top: 4px; }

/* ---------- Tables ---------- */
table.meta-table, table.list-table, table.ts-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.meta-table td { padding: 4px 0; }
table.list-table th, table.list-table td { padding: 11px 10px; border-bottom: 1px solid var(--line); text-align: left; }
table.list-table th { background: var(--bg); font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.3px; color: var(--muted); font-weight: 600; }
table.list-table tbody tr:hover { background: #FAFBFC; }
table.list-table tfoot td { font-weight: 700; border-top: 2px solid var(--ink); border-bottom: none; padding-top: 12px; }

.table-scroll { position: relative; overflow-x: auto; margin: 16px 0; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--white); }
/* Edge shadows hint that a table has more columns off-screen — without
   these, a narrow viewport just shows the first few columns with no sign
   that Remarks/Freeze Day/action links etc. exist further right.
   bimqpInitTableScroll() (_lib/layout.php) toggles these classes based on
   actual scroll position, background-position pins each gradient to its
   edge regardless of how far the content inside has scrolled. */
.table-scroll { background-repeat: no-repeat; background-position: 0 0, 100% 0; background-size: 18px 100%, 18px 100%; }
.table-scroll.has-more-left { background-image: linear-gradient(to right, rgba(20, 20, 20, 0.14), rgba(20, 20, 20, 0)); }
.table-scroll.has-more-right { background-image: linear-gradient(to left, rgba(20, 20, 20, 0.14), rgba(20, 20, 20, 0)); background-position: 100% 0; }
.table-scroll.has-more-left.has-more-right { background-image: linear-gradient(to right, rgba(20, 20, 20, 0.14), rgba(20, 20, 20, 0)), linear-gradient(to left, rgba(20, 20, 20, 0.14), rgba(20, 20, 20, 0)); background-position: 0 0, 100% 0; }
/* Action columns stack several short links/messages via <br> — without this,
   the browser's table auto-layout squeezes that column and each individual
   line wraps mid-phrase (e.g. "Awaiting employee fix" breaking across 3
   lines). Force each line to stay on one line; the Dashboard's wide page
   layout gives this column enough room that it no longer needs to scroll. */
.actions-cell { white-space: nowrap; }
table.ts-table th, table.ts-table td { padding: 8px 10px; border-bottom: 1px solid var(--line); }
table.ts-table thead tr { background: var(--bg); text-align: left; }
table.ts-table thead th { font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.3px; color: var(--muted); font-weight: 600; }
tr.row-sunday { background: var(--bg-red-wash); }
table.ts-table tfoot td { font-weight: 700; border-top: 2px solid var(--ink); border-bottom: none; background: var(--bg); }
input.hrs-input { width: 60px; padding: 6px; text-align: center; }
input.remarks-input { width: 130px; padding: 6px; }
td.center { text-align: center; }

/* ---------- Auth pages ---------- */
.auth-shell {
  min-height: calc(100vh - 100px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
}
.auth-card {
  background: var(--white);
  border-radius: 16px;
  box-shadow: var(--shadow);
  padding: 40px 36px;
  max-width: 420px;
  width: 100%;
  border-top: 4px solid var(--brand);
}
.auth-logo { display: block; margin: 0 auto 20px; height: 40px; }

/* ---------- Nav grid (Accounts Dashboard hub) ---------- */
.nav-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 14px;
  margin-top: 8px;
}
.nav-tile {
  display: block;
  padding: 18px 20px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius);
  text-decoration: none;
  transition: all 0.15s ease;
}
.nav-tile:hover { border-color: var(--brand); box-shadow: 0 4px 14px rgba(232,70,59,0.12); transform: translateY(-1px); }
.nav-tile-title { display: block; font-weight: 700; font-size: 14.5px; color: var(--ink); margin-bottom: 4px; }
.nav-tile-desc { display: block; font-size: 12.5px; color: var(--muted); line-height: 1.4; }

/* ---------- Footer ---------- */
.footer {
  text-align: center;
  color: var(--muted);
  font-size: 12px;
  padding: 24px 20px;
  border-top: 1px solid var(--line);
}
.footer p { margin: 0 0 6px; }
.footer p:last-child { margin-bottom: 0; }
.footer a { color: var(--muted); text-decoration: underline; }
.footer a:hover { color: var(--brand); }
/* &hearts; is a plain text glyph — it inherits the footer's muted grey
   instead of showing as red like an emoji heart would, so it needs an
   explicit brand-red color. The gentle pulse is just a small on-brand
   flourish (same red as the topbar underline / primary buttons). */
.footer-heart {
  display: inline-block;
  color: var(--brand);
  animation: bimqp-heartbeat 1.8s ease-in-out infinite;
}
@keyframes bimqp-heartbeat {
  0%, 100% { transform: scale(1); }
  15% { transform: scale(1.25); }
  30% { transform: scale(1); }
  45% { transform: scale(1.15); }
  60% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .footer-heart { animation: none; }
}

/* ---------- Responsive ---------- */
/* Nothing above sets a fixed px width anywhere except the nav-profile
   dropdown, so the safety net is mostly: let flex/grid containers wrap,
   shrink padding so content isn't fighting the viewport for space, and wrap
   every wide table in horizontal scroll instead of letting it blow out the
   page width. html/body never scroll sideways because of this — an
   individual .table-scroll does instead. */
html, body { overflow-x: hidden; }

@media (max-width: 860px) {
  .topbar-inner { flex-wrap: wrap; row-gap: 10px; padding: 10px 16px; }
  .nav { gap: 14px; }
  .page { padding: 0 16px; margin: 20px auto; }
  .card { padding: 20px; }
  .form-grid { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
  .brand-text { display: none; } /* logo alone is enough once space is tight */
  .nav { gap: 10px; }
  .nav a { font-size: 13px; }
  .nav-profile-trigger .nav-user { display: none; } /* avatar + caret still shows who's the trigger */
  .nav-profile-menu { right: -10px; width: min(240px, calc(100vw - 32px)); }
  h1 { font-size: 18px; }
  .card { padding: 16px; }
  .inline-form { gap: 12px; }
  .auth-card { padding: 28px 22px; }
}

/* Every wide data table gets the same horizontal-scroll treatment the
   daily-hours grid already used, instead of overflowing the page. Narrow
   tables (e.g. a 2-column pay preview) are unaffected — overflow-x:auto on
   a container that doesn't overflow does nothing visually. */
.table-scroll { -webkit-overflow-scrolling: touch; }

/* ---------- Toast notifications ----------
   Floating, auto-dismissing confirmations (bimqpToast() in _lib/layout.php)
   for one-off "you just did something" messages — replaces inline banners
   that used to sit in the page flow (e.g. above the employee dashboard's
   Instructions box) and push content down. Used on both the employee and
   Accounts sides. */
.toast-container {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 340px;
  max-width: calc(100vw - 32px);
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 14px 14px 14px 16px;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  background: var(--white);
  border-left: 4px solid var(--success);
  font-size: 13.5px;
  color: var(--ink);
  opacity: 0;
  transform: translateX(24px);
  transition: opacity 0.22s ease, transform 0.22s ease;
}
.toast-in { opacity: 1; transform: translateX(0); }
.toast-out { opacity: 0; transform: translateX(24px); }
.toast-error { border-left-color: var(--brand); }
.toast span { flex: 1; line-height: 1.45; }
.toast-close {
  border: none;
  background: none;
  cursor: pointer;
  font-size: 17px;
  line-height: 1;
  color: var(--muted-light);
  padding: 0;
  flex-shrink: 0;
}
.toast-close:hover { color: var(--ink); }
@media (max-width: 560px) {
  .toast-container { top: 10px; right: 10px; left: 10px; width: auto; max-width: none; }
}

/* ---------- Timesheet signatures + print ----------
   Physical manager sign-off still happens on paper, so the printed
   timesheet needs a blank box for the manager. The employee's own signature
   is uploaded once (upload-signature.php) and embedded as an image instead.
   .ts-print-header (logo + title) and .print-only (the manager's box) only
   appear in print — on screen the topbar logo/<h1> cover the former, and the
   latter isn't the employee's business day-to-day. */
.ts-print-header, .print-only { display: none; }
/* space-between pins the two signature boxes to the outer corners of the
   row — Employee Signature flush against the left edge (under Total),
   Reporting Supervisor flush against the right edge — instead of either
   one drifting toward the middle. */
.ts-signature-block { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 40px; margin: 28px 0 0; }
.ts-signature-box { flex: 0 1 auto; min-width: 200px; text-align: center; }
.ts-signature-box-employee { text-align: left; min-width: 160px; }
.ts-signature-box-manager { text-align: right; }
.ts-sign-line { border-bottom: 1px solid var(--ink); height: 40px; }
.signature-preview { display: block; margin: 0 0 4px; max-height: 54px; max-width: 100%; width: auto; object-fit: contain; }
.ts-sign-label { margin: 6px 0 0; font-size: 12.5px; font-weight: 600; color: var(--ink); }

/* Printed output: fits a full 28-31 day month on a single A4 page, while
   staying comfortably readable (not the earlier 7.5px squeeze). If a break
   is ever unavoidable it must fall between rows (never mid-row), with the
   column headers repeating at the top of the next page. */
@media print {
  .no-print, .topbar, .footer, .alert { display: none !important; }
  .print-only { display: block !important; }
  table.print-only { display: table !important; }
  body { background: #fff; font-size: 9.5px; line-height: 1.15; }
  .page, .page-wide { max-width: none; margin: 0; padding: 0; }
  /* The rounded red-bordered frame around the whole printed sheet, per the
     layout reference — replaces the on-screen card's shadow/plain border.
     It's stretched to the full printable A4 height (297mm - 2*5mm page
     margin) and laid out as a column so the signature row can be pinned to
     the very bottom via margin-top:auto below — a full page-height frame
     with the signature anchored at its base, instead of the box shrinking
     to fit content and leaving a dead gap of plain white page beneath it. */
  .card {
    box-shadow: none; border: 1.5px solid var(--brand); border-radius: 14px;
    padding: 16px 20px; margin: 0; min-height: 287mm;
    display: flex; flex-direction: column;
  }
  .card form { display: flex; flex-direction: column; flex: 1 1 auto; }
  /* Symmetric left+right padding (not just padding-right) so text-align:center
     centers the title on the true page width — the logo sits inside the
     right-hand padding reserve instead of stealing space from one side only.
     The extra card padding above (16px vs the old 7px) is what actually
     gives the logo clearance from the box's rounded corner — it was sitting
     almost flush against the curve before. */
  .ts-print-header { display: block; position: relative; text-align: center; margin-bottom: 5px; padding: 0 110px; }
  .ts-print-logo { position: absolute; top: 50%; right: 0; transform: translateY(-50%); height: 34px; width: auto; }
  .ts-print-title h2 { margin: 0; font-size: 17px; letter-spacing: 1.1px; text-transform: uppercase; }
  .ts-print-title p { margin: 1px 0 0; font-size: 10px; color: #555; text-transform: uppercase; letter-spacing: 0.5px; }
  table.meta-table td { padding: 0 0; font-size: 9px; }
  /* Name / NRIC / Client Company spread edge-to-edge in one row instead of
     a lopsided 2-column table with a dead gap in the middle. */
  .ts-print-meta { display: flex; justify-content: space-between; gap: 16px; font-size: 10px; margin-bottom: 3px; padding-bottom: 3px; border-bottom: 1px solid #ddd; }
  .table-scroll { overflow: visible; border: none; margin: 3px 0; }
  /* Auto layout can't resolve a percentage-width input's column size (the
     input needs a definite parent width first) — fixed layout with explicit
     column widths breaks that circularity so Remarks can actually expand
     into the space the other five compact columns free up. */
  table.ts-table { table-layout: fixed; border: 1px solid #ddd; }
  table.ts-table th, table.ts-table td { padding: 1.5px 6px; font-size: 9.5px; border-bottom: 1px solid #ddd; border-right: 1px solid #eee; }
  table.ts-table th:last-child, table.ts-table td:last-child { border-right: none; }
  /* Remarks is blank on most rows (only "SUNDAY" auto-fills) — giving it
     42% of the row left a huge dead gap of whitespace after each short
     entry. Rebalanced so the other five columns breathe more and Remarks
     still comfortably fits a full sentence when one is written. Working
     Hours only ever holds one digit ("8" or "0") — 14% of the row width
     left it looking like a mostly-empty column with a number stranded at
     the far right edge, so it's narrowed. Every column is centered so the
     header label and its data line up the same way across the whole table
     instead of a mixed left/right/center scheme. */
  table.ts-table th, table.ts-table td { text-align: center; }
  table.ts-table th:nth-child(1), table.ts-table td:nth-child(1) { width: 11%; }
  table.ts-table th:nth-child(2), table.ts-table td:nth-child(2) { width: 11%; }
  table.ts-table th:nth-child(3), table.ts-table td:nth-child(3) { width: 13%; }
  table.ts-table th:nth-child(4), table.ts-table td:nth-child(4) { width: 14%; }
  table.ts-table th:nth-child(5), table.ts-table td:nth-child(5) { width: 16%; }
  table.ts-table th:nth-child(6), table.ts-table td:nth-child(6) { width: 35%; }
  /* Header gets a branded tint + a bolder rule underneath so it reads as a
     real table head, not just another row — the light grid above (right
     borders between every column, a border around the whole table) is what
     was missing before: horizontal rules only, nothing to anchor columns. */
  table.ts-table thead th {
    background: var(--bg-red-wash); color: var(--brand-dark); font-size: 9px;
    letter-spacing: 0.2px; border-bottom: 1.5px solid var(--brand);
    padding-top: 3px; padding-bottom: 3px; white-space: nowrap;
  }
  /* Repeat the header row at the top of every printed page the table spans,
     and never let a single day's row be split across a page boundary. tfoot
     is explicitly demoted from its default paged-media role (a footer that
     repeats at the bottom of *every* page, each showing the same grand
     total) to a normal row group, so Total prints exactly once, after the
     last day — this matters if a longer month ever does spill to a 2nd page. */
  table.ts-table thead { display: table-header-group; }
  table.ts-table tfoot { display: table-row-group; }
  table.ts-table tr { page-break-inside: avoid; break-inside: avoid; }
  tr.row-sunday { background: #fafafa; }
  .badge { border: 1px solid #999; background: #fff !important; color: #333 !important; padding: 1px 4px; }
  /* !important on font-size here isn't decorative — the generic
     "form input[type=number]" rule (font-size: 14px, used for normal on-screen
     forms) outranks a plain "input.hrs-input" selector on specificity alone
     (2 element selectors + an attribute beats 1 element + 1 class), media
     query or not. Without !important the printed hour inputs render at 14px
     next to 8.5px plain-text cells — exactly the size mismatch that made
     Working Hours look "odd" against Worked Hrs/OT next to it.
     .ts-normal-hrs is a plain <td>, not an <input> — it never had a native
     border to strip, so it's deliberately left out of "border: none" here.
     Grouping it in with the inputs previously wiped out that cell's own
     grid border !important, leaving Working Hours as the one column with
     no row divider under its numbers while every other column kept theirs. */
  input.hrs-input, input.remarks-input {
    border: none !important; background: transparent !important; padding: 0 !important;
  }
  input.hrs-input, input.remarks-input, .ts-normal-hrs {
    font-size: 9.5px !important; color: #000 !important; -webkit-text-fill-color: #000 !important; opacity: 1 !important;
  }
  /* Every column centered — header label and its data line up the same
     way all the way across, instead of a mixed left/right/center scheme. */
  input.hrs-input, .ts-normal-hrs, input.remarks-input { width: 100%; text-align: center; text-overflow: ellipsis; } /* the fixed 130px screen width would clip longer remarks on paper; ellipsis is a safety net for the rare remark too long even for the widened print column */
  /* Consistent vertical anchoring across plain-text cells and input cells —
     without this, the taller input boxes could sit a hair off from the
     baseline of neighboring plain-text cells in the same row. */
  table.ts-table td, table.ts-table th { vertical-align: middle; }
  input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
  /* The line itself must leave real physical room for the manager to sign
     by hand on paper — this is the one place in the document that can't be
     shrunk to save space; the table rows above give way instead.
     margin-top:auto (rather than a fixed value) is what pins this block to
     the bottom of the full-height .card/.card>form flex column above, so
     a short month doesn't leave a dead gap of plain white page below it —
     the signature row always sits right at the base of the frame. */
  .ts-signature-block { margin-top: auto; padding-top: 20px; page-break-inside: avoid; break-inside: avoid; }
  .ts-sign-line { height: 26px; }
  .signature-preview { max-height: 38px; }
  .ts-sign-label { margin: 2px 0 0; font-size: 9px; }
  @page { size: A4 portrait; margin: 5mm; }
}
