/* skh-polish.css — the interaction layer.
   Applies Emil Kowalski's design-engineering rules across every portal page.

   Why this file exists: each page carries its own <style> block, so there was
   nowhere to put a rule that should hold everywhere. Before this, the portal had
   435 :hover rules and 7 :active rules across 96 buttons. Hover does not exist on
   a phone, so tapping a status or a due date gave no acknowledgement at all until
   the Monday round-trip returned, which is exactly where people double-tap.

   Everything here is additive. It sets no colours and no layout, so it cannot
   fight a page's own styles. Load it AFTER the page's <style> block. */

:root{
  /* Built-in CSS easings are deliberately weak. These are the curves that make
     motion read as intentional rather than default. */
  --ease-out: cubic-bezier(.23, 1, .32, 1);      /* entrances, feels instant */
  --ease-in-out: cubic-bezier(.77, 0, .175, 1);  /* movement across the screen */
  --press: 120ms;                                 /* press feedback must be quick */
}

/* ---------------------------------------------------------------- press state
   The single highest-impact rule in this file. Every control acknowledges a tap.
   :active fires on touch as well as mouse, which :hover never does. */
button,
[role="button"],
summary,
.btn, .sk-btn, .wn-btn, .addbtn, .skh-acard, .chip, .pill, .tab,
[data-edit],
a.btn, a.sk-btn{
  transition: transform var(--press) var(--ease-out);
  -webkit-tap-highlight-color: transparent;   /* replaced by our own feedback */
  touch-action: manipulation;                  /* kills the 300ms tap delay */
}
button:active,
[role="button"]:active,
summary:active,
.btn:active, .sk-btn:active, .wn-btn:active, .addbtn:active,
.skh-acard:active, .chip:active, .pill:active, .tab:active,
[data-edit]:active,
a.btn:active, a.sk-btn:active{
  transform: scale(.97);
}
/* A disabled control must not pretend to respond. */
button:disabled:active,
[role="button"][aria-disabled="true"]:active,
.btn:disabled:active, .sk-btn:disabled:active{
  transform: none;
}
/* Wide rows scale badly: a full-width element shrinking 3% reads as a glitch,
   not as feedback. Give them a settle instead. */
.skh-acard:active, .row:active, tr[data-edit]:active{
  transform: scale(.995);
}

/* ---------------------------------------------------------------- focus
   Keyboard users get the same clarity as pointer users. Never remove an outline
   without replacing it. */
:focus-visible{
  outline: 2px solid var(--brand, #004682);
  outline-offset: 2px;
  /* no border-radius here: modern engines draw the outline along the element's own
     radius, and forcing 4px squared the login inputs and the pill buttons */
}

/* ---------------------------------------------------------------- skip link
   No page had one, so keyboard users traversed the whole nav on every page.
   Hidden until focused, then it is the first thing reachable. */
.skh-skip{
  position: absolute;
  left: 8px; top: -60px;
  z-index: 10000;
  padding: 10px 16px;
  background: #004682; color: #fff;
  font: 600 14px/1 var(--font, 'Titillium'), -apple-system, 'Segoe UI', sans-serif;
  border-radius: 0 0 8px 8px;
  text-decoration: none;
  transition: top 180ms var(--ease-out);
}
.skh-skip:focus{ top: 0; }

/* ---------------------------------------------------------------- toasts
   The inline task editor already raises a toast on save and on failure. Marking
   the container live means a screen reader hears it too, which matters most on
   the failure path where the old value is silently restored underneath. */
.skh-toast{
  animation: skh-toast-in var(--t-base, 180ms) var(--ease-out);
}
@keyframes skh-toast-in{
  from{ opacity: 0; transform: translateX(-50%) translateY(8px) scale(.96); }
  to  { opacity: 1; transform: translateX(-50%) translateY(0)   scale(1);   }
}

/* ---------------------------------------------------------------- reduced motion
   A person who has asked the OS for less motion gets none of the above, but
   keeps every state change. Feedback is not decoration. */
@media (prefers-reduced-motion: reduce){
  button, [role="button"], summary, .btn, .sk-btn, .wn-btn, .addbtn,
  .skh-acard, .chip, .pill, .tab, [data-edit], a.btn, a.sk-btn, .skh-skip{
    transition-duration: .01ms;
  }
  .skh-toast{ animation: none; }
  button:active, [role="button"]:active, .btn:active, .sk-btn:active,
  .wn-btn:active, .addbtn:active, [data-edit]:active{
    transform: none;
    filter: brightness(.92);   /* the acknowledgement survives, the motion does not */
  }
}

/* ---------------------------------------------------------------- touch targets
   The what's-new carousel dots are 8px circles. Padding grows the hit area to the
   44px minimum without changing how they look. */
.wn-dot{ position:relative; }
.wn-dot::after{ content:""; position:absolute; inset:-18px; }

/* phone: keep the sign-out link on one line */
a[href="/api/logout"]{white-space:nowrap}

/* ---------------------------------------------------------------- phone (2026-09-27)
   Measured at 390px: the eleven-link page nav wrapped to three or four rows and pushed the
   first content 200px down; every text input sat under 16px, so iOS zoomed the page on
   focus. The nav becomes one row that scrolls sideways (skh-sidetab.js scrolls the current
   link into view) and every field reads at 16px. Desktop is untouched. */
@media (max-width:640px){
  /* !important: the quote builder and revenue ledger set flex-wrap inline, and the field sizes
     below lose to page rules with an id or a class in the selector */
  header nav, nav[aria-label="Portal"]{
    display:flex; flex-wrap:nowrap!important; overflow-x:auto!important; overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch; scrollbar-width:none; gap:4px; width:100%;
    padding:2px 0; margin:0;
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent);
            mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent);
  }
  header nav::-webkit-scrollbar, nav[aria-label="Portal"]::-webkit-scrollbar{ display:none; }
  header nav a, nav[aria-label="Portal"] a{
    flex:none; white-space:nowrap; min-height:40px; display:inline-flex; align-items:center;
  }
  input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]), select, textarea{ font-size:16px!important; }
  .sk-link{ min-height:36px!important; }
}
