/* App-specific layout — composes with the base-case design tokens in variables.css.
   Only additions not already covered by CSS.md's component classes. */

.content { padding: var(--size-7); }

.kpi-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--size-6);
  margin-bottom: var(--size-7);
}

.kpi-card {
  flex: 1 1 12rem;
  background: white;
  border-radius: var(--size-4);
  box-shadow: var(--shadow);
  padding: var(--size-6);
}

.kpi-card .kpi-label {
  font-size: 1.1rem;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: var(--size-3);
}

.kpi-card .kpi-value {
  font-size: 2rem;
  font-weight: bold;
  color: var(--primary);
}

.kpi-card.negative .kpi-value { color: var(--secondary); }

/* Horizontal tabs adapted for a variable, larger tab count than the 25rem-fixed default */
.horizontal-tabs-bar { flex-direction: row; }
.horizontal-tab-button {
  width: auto;
  flex: 1 1 auto;
  padding: var(--size-5) var(--size-6);
  text-align: center;
  cursor: pointer;
  font-weight: bold;
}
.tab-panel { display: none; }
.tab-panel.active { display: block; }

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--size-6);
}

.form-field label {
  display: block;
  font-size: 1.1rem;
  font-weight: bold;
  color: var(--dark);
  margin-bottom: var(--size-3);
}

.form-field .hint {
  font-size: 0.95rem;
  color: var(--accent);
  font-style: italic;
  display: block;
  margin-top: var(--size-2);
}

.section-title {
  color: var(--primary);
  text-transform: uppercase;
  font-family: 'Lato Light';
  border-bottom: var(--size-1) solid var(--accent-faded);
  padding-bottom: var(--size-4);
  margin-bottom: var(--size-6);
}

.row-actions .button { margin: 0; }

table.tablesorter input[type="number"],
table.tablesorter input[type="text"],
table.tablesorter select {
  width: 100%;
  box-sizing: border-box;
  padding: var(--size-3);
  border: var(--size-1) solid var(--accent-faded);
  border-radius: var(--size-3);
}

@media print {
  #header-bar, .breadcrumb, .horizontal-tabs-bar, .no-print { display: none; }
}


/* ── Form controls ──────────────────────────────────────────────────────────
   .form-field styled its label but never itself, so each field was a plain
   block relying on whatever the shared control CSS did to the input -- which
   put labels beside boxes instead of above them, and left the inputs so faint
   they were hard to see against the panel. Both are stated here explicitly
   rather than inherited by luck. */
.form-field {
  display: flex;
  flex-direction: column;
  min-width: 0;                 /* so a long value cannot widen the grid cell */
}

.form-field .text-input,
.form-field select,
.form-field textarea {
  width: 100%;
  box-sizing: border-box;
  float: none;                  /* the shared control CSS floats these */
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--accent-faded);
  border-radius: 0.3rem;
  background: #fff;             /* not the panel's own tint */
  color: var(--dark);
  font-family: 'Lato', sans-serif;
  font-size: 1rem;
}

.form-field .text-input:focus,
.form-field select:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--accent-faded);
}

/* A select needs to look like the text inputs beside it, not like the browser
   default, or the row reads as two different kinds of control. */
.form-field select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--accent) 50%),
                    linear-gradient(135deg, var(--accent) 50%, transparent 50%);
  background-position: calc(100% - 1.1rem) 55%, calc(100% - 0.75rem) 55%;
  background-size: 0.35rem 0.35rem, 0.35rem 0.35rem;
  background-repeat: no-repeat;
  padding-right: 2rem;
}

/* The grid rows were touching, which is most of why the panel looked unfinished. */
.form-grid { row-gap: var(--size-7); }


/* ── Page offset for the fixed sidebar ──────────────────────────────────────
   .sidebar-new is position:fixed at 5.66rem collapsed, and the shared .content
   rule only centres itself -- it has no left offset, so the page sat underneath
   the sidebar. The top header already pads itself by exactly this amount
   (.new-ui-topheader.sidebar-collapsed), so matching it keeps the header and the
   page body on the same left edge.

   Also undoes .content's `text-align: center`, which is why the empty-state text
   and headings were centred: this app's pages are ordinary left-aligned
   documents, not a centred splash. */
.wrapper > .content,
.pageBody .content {
  margin-left: 5.66rem;
  padding-left: var(--size-7);
  padding-right: var(--size-7);
  text-align: left;
  max-width: none;
}





/* ── Sidebar, sized to match CRM ─────────────────────────────────────────────
   This app's shared stylesheet is an older revision whose .sidebar-item is built
   for a much heavier menu: 1.5rem type and 2rem of padding top and bottom, which
   is why it dwarfed everything else. CRM's app stylesheet is the current house
   proportion (0.95rem type, 0.75rem padding, 1.1rem icons in a fixed 1.2rem
   gutter so they line up when collapsed), so those values are reproduced here
   against this app's class names rather than left to the old defaults. */
.sidebar-new .sidebar-item {
  padding: 0;
  font-size: 0.95rem;
}
.sidebar-new .sidebar-item > a {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem var(--size-6);
  color: #fff;
  text-decoration: none;
  font-size: 0.95rem;
  border-left: 3px solid transparent;
  transition: background 0.2s, color 0.2s;
  width: 100%;
  box-sizing: border-box;
}
.sidebar-new .sidebar-item > a:hover {
  background: rgba(255,255,255,0.12);
  color: #FFDB9F;
}
/* The current page, marked the way CRM marks it. */
.sidebar-new .sidebar-item > a.active {
  border-left-color: #FFDB9F;
  background: rgba(255,255,255,0.15);
  color: #FFDB9F;
}
/* A fixed gutter, so icons sit on one vertical line whether or not labels show. */
.sidebar-new .sidebar-item i {
  font-size: 1.1rem;
  min-width: 1.2rem;
  text-align: center;
}
.sidebar-toggle-row {
  height: 4.5rem;
  border-bottom: 1px solid rgba(255,255,255,0.15);
}
.sidebar-toggle-row > a { height: 100%; }

/* Collapsed: keep the link (the shared sheet hides every child), drop the label,
   and centre what is left. */
.sidebar-new:not(.expanded) .sidebar-item > a {
  display: flex;
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
}
.sidebar-new:not(.expanded) .sidebar-item > a > span { display: none; }


/* ── Field containers ────────────────────────────────────────────────────────
   The inputs sat on the panel with almost no edge of their own, so on a light
   background you could not see where a box began or whether it held anything.
   Each field now reads as a container: a defined border, a white well against
   the panel tint, and a visibly different state when focused or disabled. */
.form-field .text-input,
.form-field select,
.form-field textarea,
.text-input-container .text-input {
  border: 1px solid #b9c2c8;
  border-radius: 0.3rem;
  background: #fff;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06);
  min-height: 2.4rem;
}

.form-field .text-input:hover,
.form-field select:hover { border-color: var(--accent); }

.form-field .text-input:focus,
.form-field select:focus,
.form-field textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(31, 119, 150, 0.18);
}

/* A placeholder should read as "nothing typed yet", not as a value. */
.form-field .text-input::placeholder { color: #98a4ac; font-style: italic; }

/* Grouped panels get an outline too, so a form reads as sections rather than a
   single undivided field of controls. */
.bordered {
  border: 1px solid var(--accent-faded);
  border-radius: 0.4rem;
  background: #fff;
}

/* Read-only mode (see the VA02/VA03 pattern used in the sibling apps): greyed,
   but deliberately still legible -- browsers dim a disabled control to a
   contrast that suits "you cannot use this" and defeats "read this", and reading
   is the entire purpose of a view screen. */
.ro-fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
.ro-fieldset .text-input:disabled,
.ro-fieldset select:disabled,
.ro-fieldset textarea:disabled {
  /* Darker than the editable state, but the box still has to be findable. The
     first attempt tinted the fill and softened the border, which made the fields
     dissolve into the panel -- you could not see where a value began without
     switching to edit, which defeats the point of a view screen. Border and text
     stay at real contrast; only the fill recedes. */
  background: #e9edef;
  color: var(--dark);
  -webkit-text-fill-color: var(--dark);   /* Safari ignores color on disabled */
  opacity: 1;
  border: 1px solid #96a2aa;
  cursor: default;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.05);
}
/* A read-only field is still a field: the label keeps its weight so the form
   reads the same in both modes. */
.ro-fieldset label { color: var(--dark); }
.ro-banner {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.5rem 0.9rem; margin-bottom: var(--size-6);
  background: var(--accent-faded); border-radius: 0.3rem;
  color: var(--accent); font-size: 0.92rem;
}
.ro-banner-edit { margin-left: auto; }


/* ── Typography inside controls ──────────────────────────────────────────────
   Form controls do not inherit font-family from the page in any browser -- they
   fall back to a UA default -- so the labels were Lato while the values the user
   actually reads were not. Numbers get tabular figures as well, so decimals line
   up in a column instead of drifting. */
.text-input, select, textarea, button, .button,
input[type="text"], input[type="number"], input[type="date"] {
  font-family: 'Lato', sans-serif;
}
.text-input[type="number"], .text-input.numeric, td.numeric {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ── Field rows of equal height ──────────────────────────────────────────────
   A label that wraps to two lines ("Contingency % — Design & Permitting") pushed
   its own input down while its neighbours stayed put, so one box in the row sat
   lower than the rest. Stretching the row and letting the label grow while the
   control stays pinned to the bottom keeps every box on the same line. */
.form-grid { align-items: stretch; }
.form-field { justify-content: flex-start; }
.form-field label { flex: 1 1 auto; display: flex; align-items: flex-end; }
.form-field .text-input,
.form-field select { margin-top: auto; }

/* ── Tab strip ───────────────────────────────────────────────────────────────
   The tabs were in a fixed-width row that overflowed into a horizontal
   scrollbar -- a scrollbar to reach a tab is worse than smaller tabs. They now
   share the width and wrap if they genuinely cannot fit. */
.horizontal-tabs-bar,
.horizontal-tab-buttons,
.horizontal-tabs {
  display: flex;
  flex-wrap: wrap;
  overflow-x: visible;
  width: 100%;
}
.horizontal-tab-button {
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Whatever was producing the scroll track under the tabs. */
.horizontal-tabs-bar::-webkit-scrollbar,
.horizontal-tab-buttons::-webkit-scrollbar,
.horizontal-tabs::-webkit-scrollbar { display: none; }
.horizontal-tabs-bar,
.horizontal-tab-buttons, .horizontal-tabs { scrollbar-width: none; overflow-x: hidden; }


/* A percent field shows its unit, so 30 cannot be read as 0.30 or 3000. */
.pct-wrap { position: relative; display: block; margin-top: auto; }
.pct-wrap .text-input { padding-right: 2rem; width: 100%; box-sizing: border-box; }
.pct-sign {
  position: absolute; right: 0.7rem; top: 50%; transform: translateY(-50%);
  color: var(--accent); pointer-events: none; font-size: 0.95rem;
}


/* ── App title, matching the rest of the estate ──────────────────────────────
   The header title was a bare <a> carrying its own font-size, weight and colour
   inline, so this app's name sat at a different size and weight from every other
   app's. These are Field Scheduling's values (static/css/sched.css), which CRM
   also uses, reproduced here so the header reads the same across the estate.

   .logo-text-fallback is display:none there because it sits behind an <img>
   logo and only appears if that fails to load. There is no logo asset in this
   repo, so it is the visible element and is shown outright. */
.app-title-block {
  display: flex;
  align-items: center;
  height: 100%;
}
.logo-text-fallback {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: #fff;
  font-weight: 600;
  font-size: 1.25rem;
  letter-spacing: 0.02em;
  text-decoration: none;
}
.logo-text-fallback i {
  font-size: 1.4rem;
  color: #d9dce0;
}


/* ── Don't animate the sidebar into its remembered state on every page load ──
   The shared stylesheet puts a blanket `transition: 0.1s` on .sidebar-new, and
   the server always renders the menu collapsed because the remembered choice
   lives in localStorage, which only the browser can read. app.js then adds
   .expanded once the DOM is ready -- so every single navigation replayed the
   open animation, which reads as the page still loading.

   The transition is worth keeping for an actual click, so it is suppressed only
   while that first state is applied. app.js adds .no-transition before it sets
   the class and drops it on the next frame. */
.sidebar-new.no-transition,
.sidebar-new.no-transition * {
  transition: none !important;
}


/* ── Font fallback ──────────────────────────────────────────────────────────
   The shared stylesheet sets `html { font-family: 'Lato' }` with no fallback
   after it, so any failure to load the webfont drops the whole app to the
   browser default -- a serif, which is how a missing COPY in the Dockerfile
   showed up as "everything looks serif" rather than as a 404 someone noticed.

   Lato still comes first and still wins whenever it loads. This only decides
   what happens when it does not, and the answer should be the nearest sans in
   the house stack rather than Times. */
html,
body {
  font-family: 'Lato', 'Segoe UI', Helvetica, Arial, sans-serif;
}
