/* ==========================================================================
   Epsom theme: the shared look for every Epsom page.
   ==========================================================================

   Used by the tech web app (public/style.css builds on it) AND the host app
   (host/window/host.css builds on it), so everything looks like one product.

   HOW TO RESTYLE: change the variables in :root below. Every page reads its
   colours, fonts and sizes from these, so one change updates everything.

   The palette comes from the Epsom logo and the login mockup:
     grey page, light-grey panels, black outlines, red brand, green action.
   ========================================================================== */

:root {
  /* Colours */
  --bg: #8a8a8a;          /* page background (mockup grey) */
  --panel: #c7c7c7;       /* cards and panels (the logo's face) */
  --row: #b3b3b3;         /* rows inside cards: 2/3 of the way from --bg to --panel */
  --row-hover: #a6a6a6;
  --ink: #000000;         /* text and outlines (the logo's border) */
  --ink-soft: #2e2e2e;    /* secondary text */
  --brand: #e7503a;       /* Epsom red (the logo's letters) */
  --action: #53843c;      /* main buttons (mockup LOGIN green) */
  --action-hover: #61974a;
  --field: #ffffff;       /* text input fields and their dropdowns ONLY (white is for filling in) */
  --link: #0000ff;        /* links (mockup CREATE ACCOUNT) */
  --good: #53843c;        /* online, saved, success */
  --warn: #f2c94c;        /* attention notes */
  --danger: #e7503a;      /* destructive buttons, errors */

  /* Type: the mockup's typewriter style. Courier New ships with Windows,
     macOS and most phones. */
  --font: "Courier New", Courier, ui-monospace, monospace;

  /* Shape: square corners and solid black outlines, like the logo. */
  --radius: 0;
  --outline: 3px solid var(--ink);
  --outline-thin: 2px solid var(--ink);
}

* { box-sizing: border-box; }

/* The `hidden` attribute must always win, even over display rules below. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px; /* 16px+ stops iPhones zooming in when you tap an input */
  background: var(--bg);
  color: var(--ink);
}

h1, h2, h3 { text-transform: uppercase; letter-spacing: 0.04em; }
h1 { font-size: 1.4rem; margin: 0 0 0.5rem; }
h2 { font-size: 1.1rem; margin: 0 0 0.75rem; }
h3 { font-size: 0.95rem; margin: 1rem 0 0.5rem; }

.muted { color: var(--ink-soft); font-size: 0.9rem; }
.small { font-size: 0.85rem; }

a, .link {
  color: var(--link);
  font-weight: 700;
  text-decoration: underline;
  text-transform: uppercase;
  cursor: pointer;
}

/* --- Top bar: black strip with the logo ---------------------------------- */

.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 0.5rem 1rem;
  background: var(--ink);
  color: var(--panel);
}
.topbar .brand { display: flex; align-items: center; gap: 0.6rem; font-weight: 700; text-transform: uppercase; }
.topbar .brand img { width: 36px; height: 36px; }
.topbar .muted { color: #b5b5b5; }

/* --- Buttons --------------------------------------------------------------- */
/* Plain <button> = main action (green). Add .secondary for a quieter one,
   .danger for destructive ones. */

button {
  font: inherit;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.6rem 1rem;
  min-height: 44px; /* comfortable tap target on tablets/phones */
  border: var(--outline-thin);
  border-radius: var(--radius);
  background: var(--action);
  color: var(--ink);
  cursor: pointer;
}
button:hover:not(:disabled) { background: var(--action-hover); }
button.secondary { background: var(--panel); }
button.secondary:hover:not(:disabled) { background: #d6d6d6; }
button.danger { background: var(--danger); }
button.danger:hover:not(:disabled) { background: #ef6a56; }
/* Yellow: "go ahead, but think about it" (e.g. Proceed anyway). */
button.warning { background: var(--warn); }
button.warning:hover:not(:disabled) { background: #f5d470; }
button:disabled { opacity: 0.5; cursor: not-allowed; }

/* --- Icons ------------------------------------------------------------------- */
/* Add a class to a button to put an icon before its text, e.g.
     <button class="ico-edit">Edit</button>
   The images are in public/img/icons (pixel art, transparent background).
   Paths here are relative to this file, so they work in the host app too. */

[class*="ico-"]::before {
  content: '';
  display: inline-block;
  width: 22px;
  height: 22px;
  margin-right: 0.45em;
  vertical-align: -5px;
  background: center / contain no-repeat;
}
.small-btn[class*="ico-"]::before { width: 16px; height: 16px; vertical-align: -3px; margin-right: 0.35em; }
.ico-edit::before { background-image: url('img/icons/edit.png'); }
.ico-delete::before { background-image: url('img/icons/delete.png'); }
.ico-save::before { background-image: url('img/icons/save.png'); }
.ico-back::before { background-image: url('img/icons/arrow-left.png'); }
.ico-next::before { background-image: url('img/icons/arrow-right.png'); }
.ico-up::before { background-image: url('img/icons/arrow-up.png'); }
.ico-down::before { background-image: url('img/icons/arrow-down.png'); }
.ico-map::before { background-image: url('img/icons/map.png'); }
.ico-warning::before { background-image: url('img/icons/warning.png'); }

/* --- Inputs ------------------------------------------------------------------ */

input, textarea, select {
  font: inherit;
  width: 100%;
  padding: 0.55rem 0.65rem;
  border: var(--outline-thin);
  border-radius: var(--radius);
  background: var(--field);
  color: var(--ink);
}
/* Date and time boxes: phones (Safari on iPhone especially) draw these their
   own way, with a minimum width of their own that can push the box (and its
   form) wider than the screen. Drawing them like plain boxes lets width: 100%
   and min-width: 0 win, keeps the date on the left, and keeps the same height
   as the other boxes even while empty. */
input[type="date"], input[type="time"] {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  min-width: 0;
  min-height: 2.45rem; /* the height of the other boxes (39px) */
  text-align: left;
}
input[type="date"]::-webkit-date-and-time-value { text-align: left; }
input::placeholder, textarea::placeholder { color: #555; text-transform: uppercase; }
input:focus, textarea:focus, select:focus { outline: 3px solid var(--brand); outline-offset: 0; }
textarea { min-height: 5rem; resize: vertical; }
input[type="checkbox"] { width: 1.4rem; height: 1.4rem; accent-color: var(--action); }

/* Locked fields (while saving, or for people who can't edit). */
input:disabled, textarea:disabled, select:disabled { background: #dcdcdc; color: #444; }
/* Shown but not typed in (e.g. the technician's name and license at Close out). */
input[readonly], textarea[readonly] { background: #dcdcdc; color: #444; }

label { display: grid; gap: 0.3rem; font-size: 0.85rem; font-weight: 700; text-transform: uppercase; }

/* --- Layout helpers ------------------------------------------------------------ */

.card {
  background: var(--panel);
  border: var(--outline);
  border-radius: var(--radius);
  padding: 1rem;
  margin-bottom: 1rem;
}
.stack { display: grid; gap: 0.75rem; }
.stack > h1, .stack > h2, .stack > p { margin: 0; }
.row { display: flex; gap: 0.5rem; align-items: center; }
.row.wrap { flex-wrap: wrap; }
.row > input, .row > select { flex: 1; }
.row-between { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }

/* --- Messages ------------------------------------------------------------------- */

.error { background: var(--danger); color: var(--ink); font-weight: 700; padding: 0.4rem 0.6rem; margin: 0; }
/* Error messages and error pop-ups get the warning icon. */
.error::before, .toast.error::before {
  content: '';
  display: inline-block;
  width: 20px;
  height: 20px;
  margin-right: 0.45em;
  vertical-align: -4px;
  background: url('img/icons/warning.png') center / contain no-repeat;
}
.info { background: var(--good); color: var(--ink); font-weight: 700; padding: 0.4rem 0.6rem; margin: 0; }
.note { background: var(--warn); color: var(--ink); border: var(--outline-thin); padding: 0.5rem 0.75rem; margin: 0 0 0.75rem; }

/* Small labels: roles, online status, counts. */
.chip, .count, .pill, .status {
  display: inline-block;
  padding: 0.1rem 0.55rem;
  border: var(--outline-thin);
  background: var(--bg);
  color: var(--ink);
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  white-space: nowrap;
}
.status.online, .pill.running { background: var(--good); }
.status.offline { background: var(--panel); color: #444; }
.status.bad { background: var(--danger); }
/* Tickets: open work is yellow, closed-out work is green. */
.status.open { background: var(--warn); }
.status.closed { background: var(--good); }
.pill { background: var(--panel); }
.pill.starting { background: var(--warn); }
.pill.failed, .pill.stopping { background: var(--danger); }

/* --- Lists of rows (members, jobsites, people) ------------------------------------ */
/* Rows inside a light-grey card use the slightly darker --row grey, so they read as boxes. */

.list { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.4rem; }
.list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.5rem 0.7rem;
  background: var(--row);
  border: var(--outline-thin);
}
.list li.empty { background: none; border: none; padding: 0; color: var(--ink-soft); }

/* --- Sign-in screens (the mockup) ------------------------------------------------ */
/* A narrow centred column: big logo, white fields, green button, blue link. */

.signin {
  max-width: 340px;
  margin: 2rem auto;
  padding: 0 1rem;
  display: grid;
  gap: 1rem;
  text-align: center;
}
.signin .logo { width: min(260px, 80%); margin: 0 auto 1rem; display: block; }
.signin h1 { font-size: 1.1rem; margin: 0; }
.signin input { text-align: center; font-size: 1.2rem; padding: 0.7rem; border: none; }
.signin input::placeholder { color: var(--ink); }
.signin input:focus { outline: 3px solid var(--ink); }
.signin button { width: 100%; font-size: 1.2rem; border: none; }
.signin .links { display: flex; justify-content: center; gap: 1.25rem; flex-wrap: wrap; font-size: 0.85rem; }
.signin .error, .signin .info { text-align: left; }

/* Card title row: heading on the left, buttons on the right. */
.card-header { margin-bottom: 0.75rem; flex-wrap: wrap; }
.card-header h2 { margin: 0; }

/* Forms laid out in two columns on wider screens; .wide spans both. */
.form-grid { display: grid; gap: 0.75rem; grid-template-columns: 1fr; text-align: left; }
/* Keep each label + box at its natural height at the top of its cell, so a
   suggestion list opening under one box doesn't stretch the box beside it. */
.form-grid > label { align-content: start; }
/* Grid cells normally refuse to get narrower than their contents; min-width: 0
   lets them shrink to the column, so one wide box (e.g. a phone's date box)
   can't stretch the form past the screen edge. */
.form-grid > label, .form-grid > .field { min-width: 0; }
@media (min-width: 560px) {
  .form-grid { grid-template-columns: 1fr 1fr; }
  .form-grid .wide { grid-column: 1 / -1; }
}

/* --- Overlays and pop-ups --------------------------------------------------------- */

/* Pop-up windows (<dialog> opened with showModal()). */
dialog {
  width: min(560px, calc(100vw - 2rem));
  max-height: calc(100vh - 2rem);
  overflow-y: auto;
  padding: 1.25rem;
  background: var(--panel);
  color: var(--ink);
  border: var(--outline);
  border-radius: var(--radius);
}
dialog::backdrop { background: rgba(0, 0, 0, 0.5); }
dialog.wide-dialog { width: min(920px, calc(100vw - 2rem)); }
.dialog-actions { justify-content: flex-end; }

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}
.overlay-box {
  background: var(--panel);
  border: var(--outline);
  padding: 1rem 2rem;
  font-weight: 700;
  text-transform: uppercase;
}

.toasts {
  position: fixed;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  gap: 0.5rem;
  z-index: 20;
  width: min(90vw, 420px);
}
.toast {
  background: var(--ink);
  color: var(--panel);
  border: var(--outline-thin);
  padding: 0.7rem 1rem;
  font-weight: 700;
}
.toast.error { background: var(--danger); color: var(--ink); }

/* The dropdown list of a dropdown box (combo.js), in both apps. Each row:
   the entry, anything on the right, and an optional grey second line.
   White like the text box it drops from (it's part of filling the box in),
   with light grey lines between the rows and a grey highlight. */
.suggestions { border: var(--outline-thin); background: var(--field); margin-top: 0.25rem; max-height: 14rem; overflow-y: auto; }
.suggestion { display: grid; grid-template-columns: 1fr auto; gap: 0 0.75rem; padding: 0.4rem 0.6rem; cursor: pointer; font-size: 0.9rem; text-transform: none; letter-spacing: 0; font-weight: 400; }
.suggestion + .suggestion { border-top: 1px solid #c4c4c4; }
.suggestion:hover, .suggestion.active { background: #e2e2e2; }
.suggestion-desc { grid-column: 1 / -1; color: var(--ink-soft); font-size: 0.8rem; font-weight: 400; }

/* Dropdown boxes (combo.js attachDropdown): [text box ▾] with the list
   floating just under it, over the fields below, like a normal dropdown.
   position: relative on .combo is what the floating list (position: absolute)
   lines itself up against. */
.combo { position: relative; }
.combo input { width: 100%; padding-right: 2.25rem; } /* room for the ▾ */
.combo-arrow {
  position: absolute; top: 0; right: 0; bottom: 0; width: 2.25rem;
  min-height: 0; padding: 0; background: none; border: none; box-shadow: none;
  color: var(--ink); font-size: 1rem; cursor: pointer;
}
.combo-arrow:hover:not(:disabled) { background: none; color: var(--ink-soft); }
.combo .suggestions {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 10;
  margin-top: 2px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.35);
}
/* Pop-ups normally scroll their own content, which would cut off a dropdown
   hanging past the bottom edge. Pop-ups with dropdowns are short, so let them
   spill over instead, but only on screens tall enough to show the whole
   pop-up (a phone on its side still needs to scroll down to Save). Wide
   pop-ups (e.g. Close out) are too tall on a phone: they keep scrolling. */
@media (min-height: 640px) {
  dialog:has(.combo):not(.wide-dialog) { overflow: visible; }
}

/* Question and message pop-ups (dialogs.js askConfirm / showMessage):
   narrower than the form pop-ups; line breaks in the message are kept. */
dialog.epsom-dialog { width: min(420px, calc(100vw - 2rem)); }
.epsom-dialog-message { margin: 0; white-space: pre-line; }
/* askChoice (dialogs.js): wider than a yes/no pop-up so its buttons share one
   row evenly; on a narrow screen (a phone) they stack. */
dialog.choice-dialog { width: min(600px, calc(100vw - 2rem)); }
.choice-buttons { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 0.6rem; }
/* A pick-only dropdown box (combo.js pickOnly): read-only, but it's a normal
   dropdown, not a locked box, so it keeps the white look and a hand cursor. */
.combo input.pick-only { background: var(--field); color: var(--ink); cursor: pointer; }

/* The calendar under a date box (calendar.js attachCalendar). It floats like
   a dropdown (.combo .calendar), white like the box it drops from: ‹ Month ›,
   then the days. Days that can't be picked are greyed out; the picked day is
   dark; today has a dark outline. */
.combo .calendar {
  position: absolute; top: 100%; left: 0; z-index: 10; margin-top: 2px;
  width: min(19rem, calc(100vw - 3rem)); padding: 0.5rem;
  background: var(--field); border: var(--outline-thin); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.35);
}
.cal-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.4rem; }
.cal-title { font-weight: 700; text-transform: uppercase; font-size: 0.9rem; }
.cal-nav { min-height: 32px; width: 36px; padding: 0; font-size: 1.2rem; line-height: 1; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal-weekday { text-align: center; font-size: 0.7rem; font-weight: 700; color: var(--ink-soft); padding: 0.15rem 0; }
.cal-day {
  min-height: 34px; padding: 0; font-size: 0.9rem; font-weight: 400; text-transform: none; letter-spacing: 0;
  background: var(--field); color: var(--ink); border: 1px solid #c4c4c4; box-shadow: none;
}
.cal-day:hover:not(:disabled) { background: #e2e2e2; }
.cal-day.today { border: 2px solid var(--ink); }
.cal-day.picked { background: var(--ink); color: var(--field); }
.cal-day:disabled { background: #eee; color: #b5b5b5; border-color: #e2e2e2; cursor: not-allowed; opacity: 1; }

/* "Remember email" / "Remember password" under a sign-in form (both apps):
   two small checkboxes side by side (stacked when there's no room). */
.remember-row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.4rem 1.2rem; font-size: 0.8rem; }
.remember-row label { display: flex; align-items: center; gap: 0.45rem; text-transform: none; letter-spacing: 0; font-weight: 400; cursor: pointer; }
.remember-row input[type="checkbox"] { width: 1.15rem; height: 1.15rem; margin: 0; }
