/* ==========================================================================
   Energy System Builder - shared stylesheet
   Loaded on every page alongside the Tailwind CDN script. Only holds the
   handful of things Tailwind's utility classes don't cover directly:
   reusable form-control classes, and small framework-glue fixes (Alpine's
   x-cloak needs an actual CSS rule to do anything).
   ========================================================================== */

:root {
  /* Change this single value to update all dashboard pieces */
  --dashboard-radius: 0.35rem; /* 16px - equivalent to rounded-xl */
}


.curve {
  border-radius: var(--dashboard-radius);
}

.curve-t {
  border-top-left-radius: var(--dashboard-radius);
  border-top-right-radius: var(--dashboard-radius);
}


/* Alpine.js: hide [x-cloak] elements until Alpine has initialized, so the
   mobile sidebar overlay doesn't flash visible on page load. */
[x-cloak] {
  display: none !important;
}

/* Shared form-control classes, used on the Inputs and Presets forms. */
.field {
  width: 100%;
  border-radius: 0.5rem;
  border: 1px solid rgb(203 213 225); /* slate-300 */
  padding: 0.5rem 0.75rem;
  font-size: 0.875rem;
  background-color: #fff;
  color: rgb(30 41 59); /* slate-800 */
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.field:focus {
  outline: none;
  border-color: rgb(59 130 246); /* blue-500 */
  box-shadow: 0 0 0 1px rgb(59 130 246);
}

/* Highlights a required field that failed server-side validation on
   redisplay - dedicated class (not a Tailwind utility) so it reliably
   overrides .field's own border-color above regardless of whether the
   Tailwind CDN script has injected its stylesheet yet. */
.field-error {
  border-color: rgb(248 113 113) !important; /* red-400 */
}
.field-error:focus {
  border-color: rgb(239 68 68) !important; /* red-500 */
  box-shadow: 0 0 0 1px rgb(239 68 68) !important;
}

.field::placeholder {
  color: rgb(148 163 184); /* slate-400 */
}

.lbl {
  display: block;
  margin-bottom: 0.25rem;
  font-size: 0.75rem;
  font-weight: 500;
  color: rgb(51 65 85); /* slate-700 */
}

/* Formatted-currency echo used by Alpine x-text spans (e.g. the RO editor
   discount field). money-field.js no longer injects these — it formats the
   input value inline instead. tabular-nums so digits don't jitter. */
.money-field-hint {
  display: inline-block;
  margin-left: 0.375rem;
  font-size: 0.6875rem;
  line-height: 1.2;
  color: rgb(100 116 139); /* slate-500 */
  font-variant-numeric: tabular-nums;
}
.money-field-hint:empty {
  display: none;
}

/* Number inputs on the Repair Order screen. The native up/down spinner
   arrows eat horizontal room, which the already-tight rows can't spare
   on a phone. Add `field-num` to any <input type="number"> to drop the
   spinners below sm (640px); tablet/desktop keep them. */
@media (max-width: 639.98px) {
  .field-num::-webkit-outer-spin-button,
  .field-num::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
  .field-num {
    -moz-appearance: textfield;
    appearance: textfield;
  }
}


/* Thin, unobtrusive scrollbar for the wide tables on the Presets page. */
.table-scroll::-webkit-scrollbar {
  height: 8px;
}
.table-scroll::-webkit-scrollbar-thumb {
  background-color: rgb(203 213 225);
  border-radius: 9999px;
}

/* Sidebar nav links get a smooth color transition instead of an abrupt swap. */
aside nav a {
  transition: background-color 0.15s ease, color 0.15s ease;
}

/* Repair Order Labor/Parts rows (project_edit.php): each row folds to a
   description-only summary on phone screens, tapped open to reveal the
   rest. This is deliberately NOT built on native <details>/<summary> -
   an earlier version was, but modern Chrome renders non-open <details>
   content in an internal ::details-content box that ignores an author
   stylesheet's attempt to force it visible via `display` overrides, so
   the "always open at sm+" trick silently failed on desktop. Instead
   each row is a plain div with an Alpine-local `rowOpen` boolean; the
   body's visibility is toggled by ordinary `hidden`/`grid` utility
   classes (mobile) versus a static `sm:grid` (tablet/desktop always
   visible, same "hidden ... sm:block" pattern already used throughout
   this app) - no native disclosure-widget internals involved at all. */

/* Payments worklist: amber pulse when arriving via ?focus= from the RO editor */
@keyframes wl-focus-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(251,191,36,.7); }
  60%  { box-shadow: 0 0 0 8px rgba(251,191,36,0); }
  100% { box-shadow: 0 0 0 0 rgba(251,191,36,0); }
}
.wl-focus-ring {
  animation: wl-focus-pulse 1.1s ease-out forwards;
}