/* ============================================================================
   TMS base — reset, typography, layout shell and the primitives that replace
   dxButton / dxTextBox / dxNumberBox / dxDateBox / dxCheckBox / dxButtonGroup.

   Everything here is scoped under `.tms` on <body> so this file can sit
   alongside the legacy AdminLTE / sb-admin-2 pages during the migration
   without touching them.
   ========================================================================== */

.tms *, .tms *::before, .tms *::after { box-sizing: border-box; }

body.tms {
  margin: 0;
  background: var(--tms-bg);
  color: var(--tms-text);
  font-family: var(--tms-font);
  font-size: var(--tms-fs-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

.tms svg.tms-i {
  width: 1em; height: 1em;
  fill: none; stroke: currentColor;
  stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round;
  flex: none;
}

/* Element resets are wrapped in :where() so they carry ZERO specificity.
   Written as `.tms button` they would score (0,1,1) and beat single-class
   component rules like .tms-btn-primary (0,1,0) — which silently strips the
   background and colour off every themed button. Do not un-wrap these. */
:where(.tms) :where(button, input, select, textarea) { font: inherit; color: inherit; }
:where(.tms) :where(button) { cursor: pointer; background: none; border: none; padding: 0; }
:where(.tms) :where(a) { color: var(--tms-accent); text-decoration: none; }
:where(.tms) :where(a:hover) { text-decoration: underline; }

/* Focus is always visible — never remove this without a replacement. */
.tms :focus-visible {
  outline: 2px solid var(--tms-accent);
  outline-offset: 2px;
  border-radius: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .tms *, .tms *::before, .tms *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

/* --- utilities --------------------------------------------------------- */
.tms-mono { font-family: var(--tms-font-mono); font-variant-numeric: tabular-nums; font-size: var(--tms-fs-cap); }
.tms-tnum { font-variant-numeric: tabular-nums; }
.tms-eyebrow {
  font-size: var(--tms-fs-micro); font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--tms-text-3);
}
.tms-muted { color: var(--tms-text-2); }
.tms-hint  { font-size: var(--tms-fs-cap); color: var(--tms-text-3); margin-top: 5px; }
.tms-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.tms-hidden { display: none !important; }
.tms-spacer { flex: 1; }

/* ============================================================================
   APP SHELL — rail + topbar + canvas
   ========================================================================== */
.tms-rail {
  position: fixed; top: 0; bottom: 0; left: 0; width: var(--tms-rail-w);
  background: var(--tms-rail);
  display: flex; flex-direction: column; align-items: center;
  padding: 10px 0; gap: 2px; z-index: var(--tms-z-rail);

  /* Deliberately NOT `overflow-y: auto`. Any overflow value other than visible
     creates a clipping box, and since the rail is only 60px wide that silently
     ate every hover tooltip. Short viewports are handled by the media query at
     the end of this block instead. */
  overflow: visible;
}

/* Only when the rail genuinely cannot fit do we allow scrolling, and then the
   tooltips are suppressed rather than half-clipped. */
@media (max-height: 640px) {
  .tms-rail { overflow-y: auto; overflow-x: hidden; scrollbar-width: none; }
  .tms-rail::-webkit-scrollbar { width: 0; }
  .tms-rail .tms-tip { display: none; }
}

.tms-rail-logo {
  width: 32px; height: 32px; border-radius: 8px; flex: none;
  background: var(--tms-rail-accent); color: var(--tms-rail-accent-ink);
  display: grid; place-items: center;
  font-weight: 800; font-size: 14px; letter-spacing: -.03em;
  margin-bottom: 12px; text-decoration: none;
}
.tms-rail-logo:hover { text-decoration: none; }

.tms-rail-btn {
  position: relative; width: 42px; height: 38px; flex: none;
  display: grid; place-items: center; border-radius: var(--tms-r);
  color: var(--tms-rail-text); font-size: 19px; text-decoration: none;
  transition: background-color var(--tms-fast), color var(--tms-fast);
}
.tms-rail-btn:hover { background: var(--tms-rail-2); color: #fff; text-decoration: none; }
.tms-rail-btn[aria-current="page"],
.tms-rail-btn.is-active { background: var(--tms-rail-2); color: #fff; }
.tms-rail-btn[aria-current="page"]::before,
.tms-rail-btn.is-active::before {
  content: ""; position: absolute; left: -9px; top: 9px; bottom: 9px;
  width: 3px; border-radius: 0 3px 3px 0; background: var(--tms-rail-accent);
}
.tms-rail-btn .tms-tip {
  position: absolute; left: 52px; top: 50%;
  transform: translateY(-50%) translateX(-4px);
  background: var(--tms-rail-2); color: #fff;
  font-size: var(--tms-fs-cap); font-weight: 550;
  padding: 5px 9px; border-radius: var(--tms-r-sm); white-space: nowrap;
  opacity: 0; pointer-events: none; z-index: 5; box-shadow: var(--tms-shadow-2);
  transition: opacity .13s, transform .13s;
}
.tms-rail-btn:hover .tms-tip,
.tms-rail-btn:focus-visible .tms-tip { opacity: 1; transform: translateY(-50%) translateX(0); }

.tms-rail-sep { width: 24px; height: 1px; background: rgba(255,255,255,.1); margin: 8px 0; flex: none; }

.tms-topbar {
  position: fixed; top: 0; left: var(--tms-rail-w); right: 0; height: var(--tms-topbar-h);
  background: var(--tms-surface); border-bottom: 1px solid var(--tms-border);
  display: flex; align-items: center; gap: 12px; padding: 0 18px;
  z-index: var(--tms-z-topbar);
}
.tms-crumb { display: flex; align-items: center; gap: 7px; font-size: var(--tms-fs-data); color: var(--tms-text-3); min-width: 0; }
.tms-crumb a { color: var(--tms-text-3); }
.tms-crumb b { color: var(--tms-text); font-weight: 650; font-size: 14.5px; letter-spacing: -.01em; }
.tms-crumb .sl { opacity: .55; }

.tms-omni {
  margin-left: auto; display: flex; align-items: center; gap: 8px;
  width: min(400px, 38vw); height: 33px; padding: 0 11px;
  background: var(--tms-surface-2); border: 1px solid transparent;
  border-radius: var(--tms-r); color: var(--tms-text-3); font-size: var(--tms-fs-data);
  transition: border-color var(--tms-fast);
}
.tms-omni:hover { border-color: var(--tms-border-strong); }
.tms-omni kbd {
  margin-left: auto; font-family: var(--tms-font-mono); font-size: 10.5px;
  background: var(--tms-surface); border: 1px solid var(--tms-border);
  border-radius: 3px; padding: 2px 5px; color: var(--tms-text-3);
}

.tms-canvas { margin-left: var(--tms-rail-w); padding-top: var(--tms-topbar-h); }
.tms-page { padding: 22px 24px 60px; max-width: 1580px; }

.tms-page-head { display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }
.tms-page-head h1 { font-size: var(--tms-fs-title); font-weight: 650; letter-spacing: -.022em; margin: 0; }
.tms-page-head p { margin: 3px 0 0; color: var(--tms-text-2); font-size: 13.5px; }
.tms-page-head .tms-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }

/* ============================================================================
   BUTTONS — replaces dxButton / dxButtonGroup
   ========================================================================== */
.tms-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 36px; padding: 0 15px; border-radius: var(--tms-r);
  font-size: 13.5px; font-weight: 600; white-space: nowrap;
  border: 1px solid transparent; text-decoration: none;
  transition: background-color var(--tms-fast), border-color var(--tms-fast), color var(--tms-fast);
}
.tms-btn:hover { text-decoration: none; }
/* Solid glyphs. Every icon in the sprite is an outline, so the base rule sets fill:none
   and strokes the path — right for all of them except a brand mark like Visual Studio,
   which only reads as itself when it is a filled silhouette. */
.tms svg.tms-i.is-solid { fill: currentColor; stroke: none; }

.tms-btn .tms-i { font-size: 15px; }
.tms-btn[disabled], .tms-btn.is-disabled { opacity: .5; pointer-events: none; }

.tms-btn-primary { background: var(--tms-accent); color: var(--tms-on-accent); }
.tms-btn-primary:hover { background: var(--tms-accent-dark); color: var(--tms-on-accent); }

.tms-btn-ghost { border-color: var(--tms-border-strong); color: var(--tms-text-2); background: var(--tms-surface); }
.tms-btn-ghost:hover { background: var(--tms-surface-2); color: var(--tms-text); }

.tms-btn-quiet { color: var(--tms-text-2); }
.tms-btn-quiet:hover { background: var(--tms-surface-2); color: var(--tms-text); }

.tms-btn-danger { background: var(--tms-danger-tint); color: var(--tms-danger); border-color: var(--tms-danger-line); }
.tms-btn-danger:hover { background: var(--tms-danger); color: var(--tms-on-danger); }

.tms-btn-sm    { height: 29px; padding: 0 10px; font-size: var(--tms-fs-data); }
.tms-btn-block { width: 100%; height: 42px; font-size: 14.5px; }

.tms-icon-btn {
  width: 33px; height: 33px; display: grid; place-items: center;
  border-radius: var(--tms-r); color: var(--tms-text-2); font-size: 17px;
  position: relative; transition: background-color var(--tms-fast), color var(--tms-fast);
}
.tms-icon-btn:hover { background: var(--tms-surface-2); color: var(--tms-text); }
.tms-icon-btn .tms-dot {
  position: absolute; top: 6px; right: 7px; width: 6px; height: 6px;
  border-radius: 50%; background: var(--tms-danger); border: 1.5px solid var(--tms-surface);
}

/* segmented control — replaces dxButtonGroup */
.tms-segment {
  display: inline-flex; gap: 1px; padding: 2px;
  background: var(--tms-surface-2); border: 1px solid var(--tms-border);
  border-radius: var(--tms-r);
}
.tms-segment button {
  padding: 5px 11px; border-radius: var(--tms-r-sm);
  font-size: var(--tms-fs-data); font-weight: 600; color: var(--tms-text-2);
  transition: background-color var(--tms-fast), color var(--tms-fast);
}
.tms-segment button:hover { color: var(--tms-text); }
.tms-segment button[aria-pressed="true"] {
  background: var(--tms-surface); color: var(--tms-text); box-shadow: var(--tms-shadow-1);
}
.tms-segment button:disabled { opacity: .55; cursor: not-allowed; }

/* Fills its container and wraps, for the sidebar — three labels like
   ACTIONABLE / DEVELOPMENT / BUG do not fit one line at ~320px. Buttons share the
   width evenly so the group reads as one control rather than ragged pills. */
.tms-segment-wrap {
  display: flex; flex-wrap: wrap; width: 100%;
}
.tms-segment-wrap button {
  flex: 1 1 auto; min-width: 0; text-align: center; white-space: nowrap;
}

/* ============================================================================
   FORM CONTROLS — replaces dxTextBox / dxNumberBox / dxDateBox / dxCheckBox
   ========================================================================== */
.tms-field { margin-bottom: 15px; }
.tms-field > label, .tms-label {
  display: block; font-size: 11.5px; font-weight: 650; letter-spacing: .05em;
  text-transform: uppercase; color: var(--tms-text-2); margin-bottom: 6px;
}
.tms-req { color: var(--tms-danger); }

.tms-input {
  width: 100%; height: 40px; padding: 0 12px;
  background: var(--tms-surface); color: var(--tms-text);
  border: 1px solid var(--tms-border-strong); border-radius: var(--tms-r);
  transition: border-color var(--tms-fast), box-shadow var(--tms-fast);
}
.tms-input:focus {
  outline: none; border-color: var(--tms-accent);
  box-shadow: 0 0 0 3px var(--tms-accent-tint);
}
.tms-input[readonly], .tms-input[disabled] {
  background: var(--tms-surface-2); color: var(--tms-text-2); cursor: not-allowed;
}
textarea.tms-input { height: auto; padding: 10px 12px; resize: vertical; line-height: 1.55; }

select.tms-input {
  appearance: none; padding-right: 34px; cursor: pointer;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--tms-text-3) 50%),
    linear-gradient(135deg, var(--tms-text-3) 50%, transparent 50%);
  background-position: calc(100% - 16px) 17px, calc(100% - 11px) 17px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.tms-input.is-invalid { border-color: var(--tms-danger); }
.tms-input.is-invalid:focus { box-shadow: 0 0 0 3px var(--tms-danger-tint); }
.tms-error {
  display: none; font-size: var(--tms-fs-cap); color: var(--tms-danger); margin-top: 5px;
}
.tms-error.is-shown { display: block; }

.tms-check { display: inline-flex; align-items: center; gap: 7px; color: var(--tms-text-2); cursor: pointer; }
.tms-check input { width: 15px; height: 15px; accent-color: var(--tms-accent); margin: 0; }

/* ============================================================================
   CARDS / PILLS / AVATARS
   ========================================================================== */
.tms-card {
  background: var(--tms-surface); border: 1px solid var(--tms-border);
  border-radius: var(--tms-r-lg); box-shadow: var(--tms-shadow-1);
}
.tms-card-h {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 16px; border-bottom: 1px solid var(--tms-border);
}
.tms-card-h h2, .tms-card-h h3 { font-size: 13.5px; font-weight: 650; margin: 0; letter-spacing: -.005em; }
.tms-card-h .tms-actions { margin-left: auto; display: flex; gap: 6px; align-items: center; }
.tms-card-b { padding: 16px; }

.tms-pill {
  display: inline-flex; align-items: center; gap: 5px; height: 21px; padding: 0 8px;
  border-radius: 999px; font-size: 11.5px; font-weight: 650; letter-spacing: .012em;
  border: 1px solid; white-space: nowrap;
}
.tms-pill::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex: none; }
.tms-pill.tms-no-dot::before { display: none; }
.tms-pill-new  { background: var(--tms-info-tint);     color: var(--tms-info);     border-color: var(--tms-info-line); }
.tms-pill-prog { background: var(--tms-progress-tint); color: var(--tms-progress); border-color: var(--tms-progress-line); }
.tms-pill-hold { background: var(--tms-warn-tint);     color: var(--tms-warn);     border-color: var(--tms-warn-line); }
/* Cost index in the activity matrix: ahead of, in line with, or behind the share the
   person's cost implies. */
.tms-pill-ok   { background: var(--tms-ok-tint);       color: var(--tms-ok);       border-color: var(--tms-ok-line); }
.tms-pill-bad  { background: var(--tms-danger-tint);   color: var(--tms-danger);   border-color: var(--tms-danger-line); }
.tms-pill-done { background: var(--tms-ok-tint);       color: var(--tms-ok);       border-color: var(--tms-ok-line); }
.tms-pill-crit { background: var(--tms-danger-tint);   color: var(--tms-danger);   border-color: var(--tms-danger-line); }
.tms-pill-mute { background: var(--tms-surface-2);     color: var(--tms-text-2);   border-color: var(--tms-border); }

.tms-av {
  width: 24px; height: 24px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  font-size: 10px; font-weight: 700; color: #fff; letter-spacing: .02em;
  border: 1.5px solid var(--tms-surface);
}
.tms-av-s { width: 20px; height: 20px; font-size: 9px; }
.tms-av-l { width: 32px; height: 32px; font-size: 12px; }
.tms-av-c1 { background: var(--tms-av-1); } .tms-av-c2 { background: var(--tms-av-2); }
.tms-av-c3 { background: var(--tms-av-3); } .tms-av-c4 { background: var(--tms-av-4); }
.tms-av-c5 { background: var(--tms-av-5); } .tms-av-c6 { background: var(--tms-av-6); }
.tms-av-stack { display: flex; }
.tms-av-stack .tms-av + .tms-av { margin-left: -7px; }

.tms-tag {
  display: inline-flex; align-items: center; gap: 4px; height: 21px; padding: 0 8px;
  border-radius: var(--tms-r-sm); background: var(--tms-surface-2);
  border: 1px solid var(--tms-border); font-family: var(--tms-font-mono);
  font-size: 11.5px; font-weight: 550; color: var(--tms-text-2);
}

/* ============================================================================
   MOBILE AND TABLET — Phase 1: the shell
   ============================================================================

   Two breakpoints, and they mean different things.

     <= 1024px  TABLET. The desktop layout mostly survives; it needs room back.
                Padding shrinks, the omni-search collapses to an icon, dialogs
                widen to fill the screen.

     <= 720px   PHONE. The layout changes shape. The rail moves from the left
                edge to the bottom, because a 60px column costs 15% of a 390px
                screen and thumbs reach the bottom, not the far left. Dialogs
                become full-height sheets rather than centred boxes.

   Everything here is layout only. No screen loses a control, and nothing is
   hidden that cannot be reached another way — a phone user who cannot get at
   something is worse off than one who has to scroll.
   ========================================================================== */

/* ---------------------------------------------------------------- tablet ---- */
@media (max-width: 1024px) {
  .tms-page { padding: 16px 16px 56px; }
  .tms-page-head { gap: 10px; margin-bottom: 14px; }

  /* The label is the first thing to go: the icon still says "search", and the
     shortcut hint is meaningless without a keyboard. */
  .tms-omni { width: auto; padding: 0 10px; }
  .tms-omni span, .tms-omni kbd { display: none; }

  .tms-modal { max-width: min(680px, calc(100vw - 32px)); }
  .tms-modal-lg { max-width: calc(100vw - 32px); }
}

/* ----------------------------------------------------------------- phone ---- */
@media (max-width: 720px) {

  /* ---- the rail moves to the bottom ---- */
  .tms-rail {
    top: auto; bottom: 0; left: 0; right: 0;
    width: auto; height: var(--tms-railbar-h);
    flex-direction: row; justify-content: space-around; align-items: center;
    padding: 0 4px; gap: 0;
    border-top: 1px solid var(--tms-border);
    overflow-x: auto; overflow-y: hidden;

    /* Clears the iOS home indicator, and is 0 everywhere else. */
    padding-bottom: env(safe-area-inset-bottom, 0);
    height: calc(var(--tms-railbar-h) + env(safe-area-inset-bottom, 0));
  }

  .tms-rail::-webkit-scrollbar { height: 0; }

  /* Hover tooltips have no meaning on a touch screen — there is no hover, and
     they would sit under the thumb that summoned them. */
  .tms-rail .tms-tip { display: none; }

  /* The logo is a decoration in a bar this size, and the separator divides
     nothing once the items sit in a row. */
  .tms-rail-logo, .tms-rail-sep { display: none; }

  .tms-rail-btn {
    flex: 0 0 auto;
    min-width: 40px; height: 42px;
    border-radius: var(--tms-r-sm);
  }

  /* An admin has ten items in this bar, which will not fit any phone. It scrolls, but a
     row cut flush at the screen edge looks broken rather than scrollable — the padding
     leaves the last item visibly short of the edge so there is something to pull. */
  .tms-rail { justify-content: flex-start; padding-right: 22px; scroll-padding-right: 22px; }

  /* The active bar runs along the TOP of the item now, not down its left edge —
     a vertical accent in a horizontal bar reads as a divider. The radius is reset
     too: the vertical version is rounded on one side only, which on a horizontal
     bar shows up as a lopsided smear. */
  .tms-rail-btn[aria-current="page"]::before,
  .tms-rail-btn.is-active::before {
    top: 0; bottom: auto; left: 6px; right: 6px;
    width: auto; height: 3px;
    border-radius: 0 0 3px 3px;
  }

  /* The spacer exists to push the profile and sign-out to the bottom of a column.
     In a row it just eats width and pulls everything apart. */
  .tms-rail .tms-spacer { display: none; }

  /* The profile item sets its own height inline for the column layout; in the bar
     it has to match its neighbours or the bar grows around it. */
  .tms-rail a.tms-rail-btn { height: 42px !important; padding: 0 !important; }

  /* ---- everything else shifts out of the rail's way ---- */
  .tms-topbar { left: 0; padding: 0 12px; gap: 8px; }

  .tms-canvas {
    margin-left: 0;
    /* Bottom padding clears the rail bar; without it the last row of any list
       sits underneath it and cannot be reached. */
    padding-bottom: calc(var(--tms-railbar-h) + env(safe-area-inset-bottom, 0));
  }

  .tms-page { padding: 14px 12px 40px; }
  .tms-page-head h1 { font-size: 20px; }

  /* Toolbars wrap instead of overflowing, and their buttons share the width
     rather than each taking their natural size and pushing the rest off. */
  .tms-actions { flex-wrap: wrap; gap: 6px; width: 100%; }
  .tms-actions > * { flex: 1 1 auto; }

  /* ---- dialogs become sheets ---- */
  /* The backdrop is a grid with place-items:center. Overriding align-items alone
     drops the sheet to the bottom but leaves it centred at its natural width, so
     justify has to be stretched explicitly for it to fill the screen. */
  .tms-modal-backdrop { place-items: end stretch; padding: 0; }

  .tms-modal,
  .tms-modal-sm,
  .tms-modal-lg {
    width: 100%; max-width: 100%;
    max-height: 92vh;
    border-radius: var(--tms-r-lg) var(--tms-r-lg) 0 0;
    border-bottom: 0;
    animation: tms-sheet .2s var(--tms-ease);
  }

  .tms-modal-b { padding-bottom: env(safe-area-inset-bottom, 0); }

  /* Footer buttons go full width and stack. A row of small buttons at the
     bottom of a sheet is the hardest thing on the screen to hit accurately. */
  .tms-modal-f { flex-wrap: wrap; gap: 8px; }
  .tms-modal-f .tms-btn { flex: 1 1 140px; justify-content: center; min-height: 42px; }

  /* ---- touch targets ---- */
  /* 42px, not the 29px a mouse is happy with. Anything below about 40 is a
     coin-toss with a thumb. */
  .tms-btn, .tms-chip, .tms-input, select.tms-input { min-height: 40px; }
  .tms-btn-sm { min-height: 38px; }

  /* Cards and panels lose their side margins so content keeps its width. */
  .tms-card { border-radius: var(--tms-r); }

  /* Anything genuinely wide scrolls in its own box rather than stretching the
     page — a horizontally scrolling PAGE breaks vertical scrolling on touch. */
  .tms-grid-scroll { -webkit-overflow-scrolling: touch; }
}

/* Sheets rise from the bottom; the desktop pop would look wrong sliding up. */
@keyframes tms-sheet {
  from { transform: translateY(14px); opacity: .6; }
  to   { transform: translateY(0);    opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .tms-modal { animation: none; }
}

/* iOS gives input[type=date] an intrinsic width of its own and ignores a percentage
   width unless the appearance is reset and the minimum content size released. Left
   alone it renders at its natural size and pushes out of whatever card it is in —
   which is why Deadline hung off the right edge of the form on an iPhone. */
input[type="date"],
input[type="datetime-local"],
input[type="time"] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
}

/* Grid and flex children refuse to shrink below their content by default, so a wide
   control keeps its parent wide no matter what the control itself is told. */
.tms-field, .tms-prop { min-width: 0; }
.tms-field > .tms-input, .tms-prop > .tms-input { width: 100%; box-sizing: border-box; }

/* Insight report pills — red for flagged modules, amber for partial-month notice. */
.tms-pill.p-red { background: var(--tms-danger-tint); color: var(--tms-danger); }
.tms-pill.p-amber { background: var(--tms-warn-tint); color: var(--tms-warn); }

