/* ============================================================
   StealthCRX — component kit, Phase 2
   ------------------------------------------------------------
   ADDITIVE. Touches neither report.css nor still-open.css, so this
   lands as its own PR. Every value below resolves against the tokens
   already declared in report.css — no new colour is invented here.

   Prefix is k- (report is r-, close-out is so-). Built against the
   real admin screens in joe-kit-screens-for-slack/, normalized:
   same shapes and spacing as the live app, inconsistencies removed.
   No screen layout or IA is changed.
   ============================================================ */

/* ------------------------------------------------------------
   0a. Kit-local tokens
   report.css carries --r-attention-bg and --r-ok-bg but no danger
   surface, and no darker danger for hover. Declared here rather than
   in report.css so this file stays additive — if they are later
   promoted into the shared block, delete this rule and nothing else
   changes. color-mix keeps them derived from --danger rather than
   being a second hard-coded red that can drift away from the first.
   ------------------------------------------------------------ */
:root {
  --k-danger-bg:    color-mix(in srgb, var(--danger) 10%, #fff);
  --k-danger-hover: color-mix(in srgb, var(--danger) 82%, #000);
  --k-danger-ring:  color-mix(in srgb, var(--danger) 14%, transparent);
  --k-on-accent:    #fff;   /* 5.9:1 on --accent, 8.7:1 on --danger */
}

/* ------------------------------------------------------------
   0b. Overflow floor
   The live app overflows horizontally at 390px. The cause is not one
   rule — it is the absence of these two. Flex and grid children default
   to min-width:auto, which refuses to shrink below content width, so any
   long email address or select label pushes the page wider than the
   viewport. Scoped to .k-shell and its descendants — it is the shell's floor,
   not a global reset, so a table or form mounted OUTSIDE a .k-shell needs the
   same two rules applied to its own container.
   ------------------------------------------------------------ */
.k-shell, .k-shell * { min-width: 0; }
.k-shell { overflow-x: clip; }

/* ============================================================
   1. App shell — top bar, no sidebar
   The gap list claimed "top bar + 280px sidebar". There is no sidebar
   in this product; the shell is a single light bar. Corrected here.
   ============================================================ */
.k-shell { background: var(--bg); min-height: 100%; }

.k-topbar {
  display: flex; align-items: center; gap: 1rem;
  flex-wrap: wrap;                        /* two rows at 390, as the app does */
  padding: 0 var(--r-gutter);
  min-height: var(--r-header-h);
  background: var(--r-nav-bg);
  border-bottom: 1px solid var(--border);
}
.k-topbar__brand { display: inline-flex; align-items: center; flex: 0 0 auto; }
.k-topbar__nav {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: .15rem; margin-left: auto;
}
.k-navlink {
  display: inline-flex; align-items: center;
  min-height: var(--r-tap);               /* gloves-on, matches the report */
  padding: 0 .7rem; border-radius: 8px;
  font-size: .95rem; text-decoration: none; color: var(--text);
  transition: background var(--r-fast) var(--r-ease);
}
.k-navlink:hover { background: var(--bg-muted); }
.k-navlink[aria-current="page"] { background: var(--accent-tint); color: var(--accent); font-weight: 600; }

@media (max-width: 640px) {
  .k-topbar { padding-block: .4rem; }
  .k-topbar__nav { margin-left: 0; width: 100%; }
  .k-navlink { padding: 0 .55rem; font-size: .9rem; }
}

.k-page { max-width: 1100px; margin: 0 auto; padding: 1.5rem var(--r-gutter) 4rem; }
.k-page__title { font-family: var(--font-display); font-size: 2rem; margin: 0 0 .35rem; }
.k-page__sub { color: var(--text-muted); margin: 0 0 1.5rem; }

/* Title + actions, without the overflow the app has at 390 */
.k-pagehead { display: flex; flex-wrap: wrap; gap: .75rem 1rem; align-items: flex-start; }
.k-pagehead__actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-left: auto; }
@media (max-width: 640px) { .k-pagehead__actions { margin-left: 0; width: 100%; } }

/* ============================================================
   2. Tabs — underline, distinct from the report's segmented control
   Segmented = two mutually exclusive views of the same data.
   Tabs = three or more sibling destinations. Different jobs, different shapes.
   ============================================================ */
.k-tabs {
  display: flex; gap: .25rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 1.5rem;
  overflow-x: auto;                        /* scrolls itself, never the page */
  scrollbar-width: none;
}
.k-tabs::-webkit-scrollbar { display: none; }
.k-tab {
  flex: 0 0 auto;
  display: inline-flex; align-items: center;
  min-height: var(--r-tap); padding: 0 .9rem;
  border: 0; background: none; cursor: pointer;
  font: inherit; font-size: .98rem; color: var(--text-muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;                     /* sit on the rule, not above it */
  transition: color var(--r-fast) var(--r-ease), border-color var(--r-fast) var(--r-ease);
}
.k-tab:hover { color: var(--text); }
.k-tab[aria-selected="true"] { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }

/* ============================================================
   3. Form controls
   The app uses raw browser defaults for select and checkbox, and one
   input (Mobile SMS) carries a different border than its siblings.
   One set, applied uniformly. Shapes and spacing are the app's.
   ============================================================ */
.k-field { margin-bottom: 1.1rem; }
.k-label { display: block; font-weight: 600; font-size: .95rem; margin-bottom: .35rem; }
.k-label__opt { font-weight: 400; color: var(--text-muted); }
.k-hint { margin: .35rem 0 0; font-size: .85rem; color: var(--text-muted); }

.k-input, .k-select, .k-textarea {
  display: block; width: 100%;
  min-height: var(--r-tap);
  padding: .6rem .75rem;
  font: inherit; font-size: 1rem; color: var(--text);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: border-color var(--r-fast) var(--r-ease), box-shadow var(--r-fast) var(--r-ease);
}
.k-textarea { min-height: 7rem; resize: vertical; }

/* Native select keeps native behaviour; only the chrome is normalized.
   ponytail: no JS listbox — the native control is accessible, and on a
   phone it opens the OS picker, which is what a gloved hand wants. */
.k-select {
  appearance: none;
  padding-right: 2.25rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235C5566' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .8rem center;
  background-size: .7rem;
}

.k-input:hover, .k-select:hover, .k-textarea:hover { border-color: var(--accent-soft); }

/* One focus treatment, every control. The report has a single global
   :focus-visible rule; a kit needs it per component so a copied block
   carries its own focus with it. */
.k-input:focus-visible, .k-select:focus-visible, .k-textarea:focus-visible,
.k-check input:focus-visible, .k-radio input:focus-visible,
.k-btn:focus-visible, .k-tab:focus-visible, .k-navlink:focus-visible,
.k-iconbtn:focus-visible, .k-tablecard__link:focus-visible, .k-tile:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 8px;
}
/* The tab strip is a scroll container (overflow-x:auto forces overflow-y:auto),
   so an outward ring is clipped top and bottom. Draw it inside instead. Declared
   after the shared rule above, which would otherwise reset the offset to 2px. */
.k-tab:focus-visible { outline-offset: -2px; }

.k-input:focus-visible, .k-select:focus-visible, .k-textarea:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
  outline-offset: 0;                       /* ring already reads; avoid a double halo */
}

/* Error. Colour is never the only carrier — the message and the icon are. */
.k-field--error .k-input,
.k-field--error .k-select,
.k-field--error .k-textarea { border-color: var(--danger); }
.k-field--error .k-input:focus-visible,
.k-field--error .k-select:focus-visible,
.k-field--error .k-textarea:focus-visible {
  outline-color: var(--danger);
  box-shadow: 0 0 0 3px var(--k-danger-ring);
}
.k-error {
  display: flex; align-items: flex-start; gap: .35rem;
  margin: .4rem 0 0; font-size: .88rem; color: var(--danger); font-weight: 500;
}
.k-error .k-icon { flex: 0 0 auto; margin-top: .12em; }

/* aria-disabled is for links, which cannot take the native attribute.
   CSS alone cannot stop Enter on a link, so pointer-events is a floor,
   not the fix — a <button> must use the real disabled attribute. */
.k-btn[aria-disabled="true"] { pointer-events: none; }

.k-input:disabled, .k-select:disabled, .k-textarea:disabled,
.k-btn:disabled, .k-btn[aria-disabled="true"] {
  background-color: var(--bg-muted);   /* NOT the shorthand — it would wipe
                                          the select's chevron background-image
                                          and leave 2.25rem of empty padding */
  color: var(--text-muted);
  cursor: not-allowed;
  opacity: .7;
}

/* Checkbox and radio — real inputs, sized up to a usable target.
   accent-color keeps native semantics and the OS focus behaviour. */
.k-check, .k-radio {
  display: flex; align-items: flex-start; gap: .6rem;
  min-height: var(--r-tap); padding: .5rem 0;
  cursor: pointer;
}
.k-check input, .k-radio input {
  flex: 0 0 auto;
  width: 1.15rem; height: 1.15rem; margin: .18rem 0 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.k-check input:disabled, .k-radio input:disabled { cursor: not-allowed; }
/* The label is the tap target, so the whole row has to read as disabled —
   cursor on the input alone leaves 90% of the hit area lying about it. */
.k-check:has(input:disabled), .k-radio:has(input:disabled) { cursor: not-allowed; }
.k-check:has(input:disabled) .k-check__label,
.k-radio:has(input:disabled) .k-check__label { color: var(--text-muted); }
.k-check__body { display: block; }
.k-check__label { font-weight: 500; }
.k-check__hint { display: block; font-size: .87rem; color: var(--text-muted); }

/* Error. A required checkbox that was not ticked is an ordinary admin-form
   failure, and the kit claimed to cover it before it did. The rail gives the
   row an edge to carry the state, since a checkbox has no border to colour. */
.k-check--error, .k-radio--error {
  border-left: 3px solid var(--danger);
  padding-left: .6rem;
  background: var(--k-danger-bg);
  border-radius: 0 6px 6px 0;
}
.k-check--error .k-check__label, .k-radio--error .k-check__label { color: var(--danger); }
.k-check--error input, .k-radio--error input { accent-color: var(--danger); outline-color: var(--danger); }

/* Fieldset card — the app's "WHO THEY ARE" / "ASSIGNMENTS" pattern */
.k-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--r-radius);
  padding: 1.25rem;
  margin-bottom: 1rem;
}
.k-card--nested { background: var(--bg); }
.k-kicker {
  font-size: .78rem; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-muted);
  margin: 0 0 .9rem;
}

/* ============================================================
   4. Buttons — primary, secondary, destructive, icon, pending
   Destructive already exists in the app ("Remove this contact");
   the gap list wrongly said it did not.
   ============================================================ */
.k-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: var(--r-tap); padding: 0 1rem;
  font: inherit; font-size: .95rem; font-weight: 600;
  border: 1px solid transparent; border-radius: 8px;
  cursor: pointer; text-decoration: none;
  transition: background var(--r-fast) var(--r-ease), border-color var(--r-fast) var(--r-ease);
}
.k-btn--primary { background: var(--accent); color: var(--k-on-accent); }
.k-btn--primary:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--accent-hover); }
.k-btn--secondary { background: var(--bg-muted); color: var(--text); border-color: var(--border); }
.k-btn--secondary:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--border); }
.k-btn--danger { background: var(--danger); color: var(--k-on-accent); }
.k-btn--danger:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--k-danger-hover); }
.k-btn--ghost { background: none; color: var(--accent); }
.k-btn--ghost:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--accent-tint); }

.k-iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--r-tap); height: var(--r-tap);
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--card-bg); color: var(--text-muted); cursor: pointer;
}
.k-iconbtn:hover { color: var(--text); border-color: var(--accent-soft); }

/* Pending — the label stays, so the button never changes width mid-request */
.k-btn[aria-busy="true"] { opacity: .8; }
.k-btn[aria-busy="true"] .k-spinner { display: inline-block; }

.k-btnrow { display: flex; flex-wrap: wrap; gap: .5rem; }

/* ============================================================
   5. Dense table → cards at 390
   Desktop keeps real table semantics. Below 720 each row becomes a card
   and every cell carries its own label from data-label, so nothing is
   read as a bare orphan value. This is the app's own pattern, made to
   hold without the horizontal overflow it currently has.
   ============================================================ */
.k-tablewrap { width: 100%; }
.k-table { width: 100%; border-collapse: collapse; font-size: .95rem; }
.k-table th {
  text-align: left; font-size: .78rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted); font-weight: 600;
  padding: .6rem .75rem; border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.k-table td { padding: .85rem .75rem; border-bottom: 1px solid var(--border); vertical-align: top; }
.k-table tbody tr:hover { background: var(--bg-muted); }
.k-table__primary { font-weight: 600; display: block; }
.k-table__sub { color: var(--text-muted); font-size: .88rem; overflow-wrap: anywhere; }
.k-table__num { text-align: right; font-variant-numeric: tabular-nums; }

/* Severity rail, the app's 3px left border */
.k-table tbody tr.is-attention td:first-child { box-shadow: inset 3px 0 0 var(--r-attention); }
.k-table tbody tr.is-danger    td:first-child { box-shadow: inset 3px 0 0 var(--danger); }

@media (max-width: 720px) {
  .k-table, .k-table tbody, .k-table tr, .k-table td { display: block; width: 100%; }
  .k-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .k-table tbody tr {
    background: var(--card-bg);
    border: 1px solid var(--border); border-radius: var(--r-radius);
    padding: .9rem; margin-bottom: .75rem;
  }
  .k-table tbody tr:hover { background: var(--card-bg); }
  .k-table td { border: 0; padding: .2rem 0; }
  .k-table td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: .72rem; letter-spacing: .06em; text-transform: uppercase;
    color: var(--text-muted); font-weight: 600; margin-top: .5rem;
  }
  .k-table td:first-child[data-label]::before { margin-top: 0; }
  .k-table__num { text-align: left; }
  .k-table tbody tr.is-attention { border-left: 3px solid var(--r-attention); }
  .k-table tbody tr.is-danger    { border-left: 3px solid var(--danger); }
  .k-table tbody tr.is-attention td:first-child,
  .k-table tbody tr.is-danger    td:first-child { box-shadow: none; }
}

/* ============================================================
   6. Severity — the full scale, red included
   Red is already in the product (dark 3+ days, offline rails, status
   squares). The gap list called it "a decision"; it is not, it is here.
   ============================================================ */
.k-sev { display: inline-flex; align-items: center; gap: .4rem; font-weight: 600; font-size: .88rem; }
.k-sev::before { content: ""; width: .6rem; height: .6rem; border-radius: 2px; flex: 0 0 auto; }
.k-sev--ok::before        { background: var(--r-ok); }
.k-sev--attention::before { background: var(--r-attention); }
.k-sev--danger::before    { background: var(--danger); }
.k-sev--ok        { color: var(--r-ok); }
.k-sev--attention { color: var(--r-attention); }
.k-sev--danger    { color: var(--danger); }

.k-pill {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .28rem .6rem; border-radius: 999px;
  font-size: .85rem; font-weight: 600; white-space: nowrap;
}
.k-pill--ok        { background: var(--r-ok-bg); color: var(--r-ok); }
.k-pill--attention { background: var(--r-attention-bg); color: var(--r-attention); }
.k-pill--danger    { background: var(--k-danger-bg); color: var(--danger); }
.k-pill--neutral   { background: var(--bg-muted); color: var(--text-muted); }

/* KPI tile — the number is the target, per the app's "tap a number" affordance */
.k-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: .6rem; }
.k-tile {
  display: block; width: 100%; text-align: left;
  background: var(--card-bg); border: 1px solid var(--border);
  border-radius: 10px; padding: .9rem 1rem;
  cursor: pointer; font: inherit;
}
.k-tile:hover { border-color: var(--accent-soft); }
.k-tile__num { font-family: var(--font-display); font-size: 1.8rem; line-height: 1; display: block;
                color: var(--text-muted); }   /* base: a count with no severity
                   modifier must not out-shout the ones that have one */
.k-tile--ok .k-tile__num        { color: var(--text-muted); }
.k-tile--attention .k-tile__num { color: var(--r-attention); }
.k-tile--danger .k-tile__num    { color: var(--danger); }
.k-tile__label { display: inline-flex; align-items: center; gap: .35rem; margin-top: .4rem; font-size: .88rem; color: var(--text-muted); }

/* ============================================================
   7. Alert — the amber band with inline actions
   ============================================================ */
.k-alert {
  border: 1px solid var(--r-attention-line);
  border-left-width: 3px;
  background: var(--r-attention-bg);
  border-radius: 8px; padding: 1rem;
  margin-bottom: 1rem;
}
.k-alert p { margin: 0 0 .6rem; color: var(--r-attention); }
.k-alert p:last-child { margin-bottom: 0; }
.k-alert--danger { border-color: var(--danger); background: var(--k-danger-bg); }
.k-alert--danger p { color: var(--danger); }
.k-alert--ok { border-color: var(--r-ok); background: var(--r-ok-bg); }
.k-alert--ok p { color: var(--r-ok); }

/* ============================================================
   8. Toast — anchored confirmation, the app's Rebuild pattern
   role="status" so it is announced without stealing focus.
   ============================================================ */
.k-toastwrap { position: relative; display: inline-block; }
.k-toast {
  position: absolute; top: calc(100% + .5rem); left: 0; right: auto; z-index: 20;
  width: max-content; max-width: min(20rem, calc(100vw - 2rem));
  background: var(--card-bg);
  border: 1px solid var(--border); border-radius: 10px;
  box-shadow: var(--r-shadow);
  padding: .8rem .9rem;
  font-size: .92rem;
  animation: k-toast-in var(--r-mid) var(--r-ease);
}
.k-toast--ok { border-left: 3px solid var(--r-ok); }
.k-toast--danger { border-left: 3px solid var(--danger); }
@keyframes k-toast-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
/* Anchored to the trigger's INLINE START and growing with the text, so it can
   never be pushed off the left edge. --end flips it for a trigger that already
   sits at the right of its container (the app's Rebuild button); use that one
   only when there is room to its left. Defaulting to --end is what put this
   panel at -182.8px on a 768 viewport. */
.k-toast--end { left: auto; right: 0; }

/* On a narrow screen the trigger
   may sit near either edge, so instead of guessing a side the wrapper goes
   full-width and the panel stretches to it — the toast can then never be
   wider than the container it lives in, whatever the trigger's position.
   Sizing off 100vw here instead would re-add the wrapper's own left inset
   as overflow, which is exactly the 390px bug this kit exists to prevent. */
@media (max-width: 560px) {
  .k-toastwrap { display: block; }
  .k-toast { left: 0; right: 0; width: auto; max-width: none; }
}
/* Above that breakpoint the panel is still right-anchored to its trigger, so
   a trigger sitting within ~20rem of its container's left edge would push the
   panel past that edge. CSS cannot detect the trigger's offset, so this is a
   choice the caller makes: add --block and the wrapper spans its container. */
.k-toastwrap--block { display: block; }
.k-toastwrap--block .k-toast { left: 0; right: 0; width: auto; max-width: none; }
@media (prefers-reduced-motion: reduce) { .k-toast { animation: none; } }

/* ============================================================
   9. Empty · error · loading
   The report always has data by the time it renders, so none of these
   existed. The app's loading today is one spinner over a blank viewport.
   ============================================================ */
.k-state {
  text-align: center;
  padding: 3rem 1.25rem;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--r-radius);
}
.k-state__icon { color: var(--text-muted); margin-bottom: .75rem; }
.k-state__title { font-weight: 600; font-size: 1.05rem; margin: 0 0 .35rem; }
.k-state__body { color: var(--text-muted); margin: 0 auto 1rem; max-width: 32rem; }
.k-state--error .k-state__icon { color: var(--danger); }

.k-spinner {
  display: inline-block; width: 1rem; height: 1rem;
  border: 2px solid var(--accent-soft); border-top-color: var(--accent);
  border-radius: 50%;
  animation: k-spin .7s linear infinite;
}
@keyframes k-spin { to { transform: rotate(360deg); } }

/* Skeleton — reserves the shape the data will occupy, so the page does
   not jump when it lands. This is the answer to the blank-viewport load. */
.k-skel {
  background: linear-gradient(90deg, var(--bg-muted) 25%, var(--border) 37%, var(--bg-muted) 63%);
  background-size: 400% 100%;
  animation: k-shimmer 1.4s ease infinite;
  border-radius: 6px;
}
@keyframes k-shimmer { from { background-position: 100% 50%; } to { background-position: 0 50%; } }
.k-skel--line { height: .8rem; margin: .45rem 0; }
.k-skel--title { height: 1.2rem; width: 40%; margin-bottom: .9rem; }
.k-skel--row { height: 3.25rem; margin-bottom: .5rem; }

/* Slow request — appears only after the wait stops feeling instant,
   so a fast response never flashes it. */
.k-slow {
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  color: var(--text-muted); font-size: .9rem;
  margin-top: .75rem;
  opacity: 0;
  animation: k-slow-in .2s var(--r-ease) 4s forwards;
}
@keyframes k-slow-in { to { opacity: 1; } }

/* Reduced motion. report.css:604 already zeroes every animation with
   `animation-duration:.01ms !important; animation-iteration-count:1 !important`.
   That is right for decoration and wrong for a spinner: it would spin once,
   instantly, then sit frozen — indistinguishable from a hung request. The
   spinner is the one element that must keep moving, so it opts out with the
   same weight. Everything else here keeps the house rule.
   The shimmer stops outright. .k-slow keeps its 4s delay and loses only
   the fade, so the message still waits before it appears.
   This block sits AFTER .k-slow deliberately: at equal specificity the
   later rule wins, so declaring it earlier let .k-slow's `animation`
   shorthand quietly reset the duration again. */
@media (prefers-reduced-motion: reduce) {
  .k-spinner {
    animation-duration: 2.4s !important;
    animation-iteration-count: infinite !important;
  }
  .k-skel { animation: none; }
  .k-slow { animation-duration: 0s; }
}

/* Visually hidden, still announced. For data carried by an icon alone —
   the kit says colour never carries meaning on its own; the same applies
   to a glyph standing in for a value. */
.k-vh {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; white-space: nowrap;
  clip-path: inset(50%);
}

/* ============================================================
   10. Icons
   Stroke-based, currentColor, 1.6 width, 24-box. One <symbol> sprite —
   swap the sprite and every icon changes, which is the point: the Sept
   rebrand may replace this set wholesale.
   ============================================================ */
.k-icon { width: 1.15em; height: 1.15em; display: inline-block; vertical-align: -.15em; fill: none;
          stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.k-icon--lg { width: 2rem; height: 2rem; stroke-width: 1.4; }
.k-sprite { display: none; }
