.fs-workspace-welcome {
  padding: var(--fs-space-6);
  background:
    linear-gradient(
      90deg,
      color-mix(in srgb, var(--fs-color-surface) 98%, transparent),
      color-mix(in srgb, var(--fs-color-surface) 92%, transparent)
    ),
    url("../../backgrounds/light-background.png");
}

.fs-workspace-welcome > span,
.fs-workspace-feature-label {
  color: var(--fs-color-text-secondary);
  font-size: var(--fs-text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.fs-workspace-welcome h2 {
  margin-top: var(--fs-space-2);
  color: var(--fs-color-text);
  font-size: 28px;
  font-weight: 700;
}

.fs-workspace-welcome p {
  max-width: 720px;
  margin-top: var(--fs-space-2);
  color: var(--fs-color-text-secondary);
  font-size: var(--fs-text-sm);
}

.fs-workspace-features {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--fs-space-3);
}

.fs-workspace-feature {
  display: grid;
  gap: var(--fs-space-2);
  min-height: 170px;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}

@media (hover: hover) {
  .fs-workspace-feature:hover {
    border-color: color-mix(in srgb, var(--fs-color-primary) 28%, var(--fs-color-border));
    box-shadow: var(--fs-shadow-md);
  }
}

.fs-workspace-feature > strong {
  margin-top: auto;
  color: var(--fs-color-text);
  font-size: var(--fs-text-xl);
}

.fs-workspace-feature p {
  color: var(--fs-color-text-secondary);
  font-size: var(--fs-text-sm);
}

.fs-workspace-feature-action {
  color: var(--fs-color-primary-hover);
  font-size: var(--fs-text-sm);
  font-weight: 700;
}

.fs-workspace-default {
  display: grid;
  gap: var(--fs-page-gap);
}

/*
 * Company home.
 *
 * One panel read from top to bottom, not a stack of cards: a cover, then a
 * hairline between each section. A page about the company is the one screen in
 * the product with no data on it, so what it has instead of figures is room —
 * the sections are wide, the photographs are large, and every list entry is a
 * plate of its own rather than a bullet in a paragraph.
 *
 * The client application owns the copy and the photographs; the section shapes
 * are shared, so two client homes cannot drift into two different pages.
 */
.fs-workspace-home {
  display: block;
  padding: 0;
  overflow: hidden;
}

/* The cover carries the recessed ground, so the panel opens before it reports. */
.fs-workspace-home__hero {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(230px, 0.46fr);
  align-items: stretch;
  gap: var(--fs-space-5);
  padding: var(--fs-space-6);
  overflow: hidden;
  background: var(--fs-color-surface-subtle);
  border-bottom: 1px solid var(--fs-color-border-subtle);
}

.fs-workspace-home__hero-copy h1 {
  max-width: 640px;
  margin: var(--fs-space-1) 0 var(--fs-space-3);
  color: var(--fs-color-text);
  font-size: var(--fs-text-2xl);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.fs-workspace-home__hero-copy p,
.fs-workspace-home__section header p,
.fs-workspace-home__highlights p,
.fs-workspace-home__section figcaption {
  color: var(--fs-color-text-secondary);
  line-height: 1.65;
}

.fs-workspace-home__hero-copy p {
  margin: 0 0 var(--fs-space-2);
  font-size: var(--fs-text-md);
}

.fs-workspace-home__hero-copy p:last-child {
  margin-bottom: 0;
}

/* The media column matches the copy it stands beside instead of setting its own height. */
.fs-workspace-home__hero-media {
  display: grid;
  gap: var(--fs-space-2);
  height: 100%;
  min-height: 188px;
}

.fs-workspace-home > .fs-company-news-grid {
  border-bottom: 1px solid var(--fs-color-border-subtle);
}

/*
 * The photo is taken out of flow so it never sizes the panel: it fills whatever
 * height the copy beside it asks for, top edge to bottom edge.
 */
.fs-workspace-home figure {
  position: relative;
  margin: 0;
  min-height: 0;
  overflow: hidden;
  background: var(--fs-color-surface-subtle);
  border: 1px solid var(--fs-color-border-subtle);
  border-radius: var(--fs-radius-lg);
}

.fs-workspace-home figure img {
  position: absolute;
  display: block;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.fs-workspace-home__gallery {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--fs-space-2);
}

/*
 * A partner mark is a logo, not a photograph: it stands inside its plate whole,
 * with air around it. These rules follow the photo rules above rather than
 * preceding them — at equal specificity the later declaration is the one that
 * wins, and stated first they were silently overruled and the marks were
 * cropped to fill.
 */
.fs-workspace-home__gallery figure {
  min-height: 110px;
  border-radius: var(--fs-radius-md);
}

.fs-workspace-home__gallery figure img {
  inset: var(--fs-space-3);
  width: auto;
  height: auto;
  object-fit: contain;
}

/*
 * The panel itself is the two-column grid, not the block inside it. That lets
 * the photo span the heading row as well and reach the full height of the
 * panel, instead of hanging below the heading with dead space beside it.
 */
.fs-workspace-home__section {
  display: grid;
  align-content: start;
  gap: var(--fs-space-3);
  padding: var(--fs-space-6);
  border-bottom: 1px solid var(--fs-color-border-subtle);
}

.fs-workspace-home__section:last-child {
  border-bottom: 0;
}

.fs-workspace-home__section:has(.fs-workspace-home__section-content figure) {
  grid-template-columns: minmax(0, 1fr) minmax(240px, 0.6fr);
  grid-template-rows: auto 1fr;
}

.fs-workspace-home__section > header,
.fs-workspace-home__highlights,
.fs-workspace-home__section-content ul {
  grid-column: 1;
}

/* A wrapper with no layout of its own: its children are the panel's own grid items. */
.fs-workspace-home__section-content {
  display: contents;
}

.fs-workspace-home__section > header {
  display: grid;
  gap: var(--fs-space-1);
}

.fs-workspace-home__section h2 {
  margin: 0;
  color: var(--fs-color-text);
  font-size: var(--fs-text-xl);
  font-weight: 700;
}

.fs-workspace-home__section header p,
.fs-workspace-home__highlights p {
  margin: 0;
  font-size: var(--fs-text-sm);
}

.fs-workspace-home__highlights {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--fs-space-3);
}

/*
 * An advantage is a claim, not a metric: it gets a plate so five of them read as
 * five statements rather than one paragraph broken into columns.
 */
.fs-workspace-home__highlights article {
  padding: var(--fs-space-4);
  background: var(--fs-color-surface-subtle);
  border: 1px solid var(--fs-color-border-subtle);
  border-radius: var(--fs-radius-lg);
}

.fs-workspace-home__highlights h3 {
  display: flex;
  align-items: center;
  gap: var(--fs-space-2);
  margin: 0 0 var(--fs-space-2);
  color: var(--fs-color-primary-text);
  font-size: var(--fs-text-md);
  font-weight: 600;
}

/*
 * The tick is the shared icon under a mask rather than a character: a glyph
 * from the text font changes shape with the font and cannot take a token colour.
 */
.fs-workspace-home__highlights h3::before,
.fs-workspace-home__section-content li::before {
  display: block;
  flex: 0 0 18px;
  width: 18px;
  height: 18px;
  content: "";
  background: var(--fs-color-success);
  mask-image: url("../../icons/task/check-circle.svg");
  mask-position: center;
  mask-repeat: no-repeat;
  mask-size: 18px 18px;
  -webkit-mask-image: url("../../icons/task/check-circle.svg");
  -webkit-mask-position: center;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-size: 18px 18px;
}

/* Short catalogue entries: two calm columns instead of one long ladder. */
.fs-workspace-home__section-content ul {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-content: start;
  gap: var(--fs-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Each entry stands on its own plate, so the eye counts them instead of reading them. */
.fs-workspace-home__section-content li {
  display: flex;
  align-items: center;
  gap: var(--fs-space-3);
  min-height: 44px;
  padding: var(--fs-space-2) var(--fs-space-3);
  color: var(--fs-color-text);
  background: var(--fs-color-surface-subtle);
  border: 1px solid var(--fs-color-border-subtle);
  border-radius: var(--fs-radius-md);
  font-size: var(--fs-text-md);
  font-weight: 600;
  line-height: 1.4;
}

.fs-workspace-home__section-content figure {
  grid-column: 2;
  grid-row: 1 / -1;
  min-height: 168px;
}

/*
 * A photograph that explains itself keeps the caption below it rather than over
 * its foot: text on an unknown image is legible only by luck, and the sentence
 * here is the point of the picture.
 */
.fs-workspace-home__section-content figure:has(figcaption) {
  display: grid;
  grid-template-rows: minmax(160px, 1fr) auto;
}

.fs-workspace-home__section-content figure:has(figcaption) img {
  position: static;
  min-height: 0;
}

.fs-workspace-home__section figcaption {
  padding: var(--fs-space-3);
  border-top: 1px solid var(--fs-color-border-subtle);
  font-size: var(--fs-text-sm);
}

/*
 * Company home: photo covers.
 *
 * Друга дозволена форма для клієнтської головної. Замість колонки копії з фото
 * поруч блок кладе текст на саме фото — так, як це вже робить mobile cover і
 * плитка новини. Причина та сама: сторінка про компанію не має даних, а має
 * склад, який видно, і колонка тексту поруч із маленьким кадром показує його
 * гірше, ніж кадр на всю ширину панелі.
 *
 * Затемнення обов'язкове й однакове для всіх таких блоків, бо яскравості
 * клієнтського фото Stoneware не знає: контраст тут дає градієнт, а не удача
 * кадру. Текст білий і має ту саму тінь, що й підпис новини на фото — одне
 * значення на весь продукт, щоб два фото-блоки не розійшлися.
 *
 * Стара форма `fs-workspace-home__hero` лишається: її беруть головні, у яких
 * фото є ілюстрацією поруч із текстом, а не поверхнею під ним.
 */
.fs-workspace-home__cover,
.fs-workspace-home__closing {
  position: relative;
  isolation: isolate;
  display: grid;
  align-content: end;
  overflow: hidden;
}

.fs-workspace-home__cover > img,
.fs-workspace-home__closing > img {
  position: absolute;
  z-index: 0;
  display: block;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/*
 * Градієнт тримає низ блока, де стоїть копія, і лишає верх кадру відкритим.
 * Верхні відсотки все ж не нульові: заголовок на світлому небі без них
 * читається лише тоді, коли небо темне.
 */
.fs-workspace-home__cover::after,
.fs-workspace-home__closing::after {
  position: absolute;
  z-index: 1;
  inset: 0;
  content: "";
}

.fs-workspace-home__cover::after {
  background: linear-gradient(
    180deg,
    rgb(20 17 13 / 34%) 0%,
    rgb(20 17 13 / 28%) 28%,
    rgb(20 17 13 / 74%) 70%,
    rgb(20 17 13 / 94%) 100%
  );
}

.fs-workspace-home__closing::after {
  background: linear-gradient(
    180deg,
    rgb(20 17 13 / 22%) 0%,
    rgb(20 17 13 / 58%) 58%,
    rgb(20 17 13 / 90%) 100%
  );
}

.fs-workspace-home__cover {
  min-height: 380px;
  border-bottom: 1px solid var(--fs-color-border-subtle);
}

.fs-workspace-home__cover-copy,
.fs-workspace-home__closing-copy {
  position: relative;
  z-index: 2;
  display: grid;
  min-width: 0;
}

.fs-workspace-home__cover-copy {
  gap: var(--fs-space-3);
  max-width: 760px;
  padding: var(--fs-space-6);
}

/*
 * Марка компанії каже себе один раз і малими літерами: заголовок нижче вже
 * несе назву, і повторений тим самим кеглем він читався б як два заголовки.
 * Риска ліворуч — не декор, а те, що відрізняє надзаголовок від абзацу.
 */
.fs-workspace-home__kicker {
  display: flex;
  align-items: center;
  gap: var(--fs-space-3);
  margin: 0;
  color: #fff;
  font-size: var(--fs-text-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-shadow: 0 1px 3px rgb(20 17 13 / 45%);
}

.fs-workspace-home__kicker::before {
  flex: 0 0 28px;
  height: 2px;
  background: currentcolor;
  border-radius: var(--fs-radius-pill);
  content: "";
}

/* Заголовок обкладинки більший за заголовок панелі: у нього під текстом фото,
   а не поверхня сторінки, тому дрібний кегель тут просто тоне. */
.fs-workspace-home__cover-copy h1 {
  max-width: 720px;
  margin: 0;
  color: #fff;
  font-size: clamp(var(--fs-text-2xl), 2.4vw, 32px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.18;
  text-shadow: 0 1px 3px rgb(20 17 13 / 45%);
}

.fs-workspace-home__cover-copy p,
.fs-workspace-home__closing-copy p {
  max-width: 680px;
  margin: 0;
  color: #fff;
  font-size: var(--fs-text-md);
  line-height: 1.6;
  text-shadow: 0 1px 3px rgb(20 17 13 / 45%);
}

/*
 * Розділ, який весь лежить на кадрі.
 *
 * Плитка з рамкою й заливкою всередині вже обведеної panel читається як панель
 * у панелі, і вісім таких плиток важать більше, ніж те, що на них написано. Тут
 * поверхню під переліком дає саме фото: лишаються позначка й слово, а рамок і
 * заливок немає зовсім. Форму беруть розділи, які є переліком — товарні
 * напрями, типи клієнтів; розділ із твердженнями лишається світлим, інакше
 * сторінка стає суцільною чергою темних кадрів.
 */
.fs-workspace-home__cover--section {
  min-height: 340px;
  border-bottom: 1px solid var(--fs-color-border-subtle);
}

.fs-workspace-home__cover--section .fs-workspace-home__cover-copy {
  gap: var(--fs-space-4);
  max-width: none;
}

.fs-workspace-home__cover-copy h2 {
  margin: 0;
  color: #fff;
  font-size: var(--fs-text-xl);
  font-weight: 700;
  letter-spacing: -0.01em;
  text-shadow: 0 1px 3px rgb(20 17 13 / 45%);
}

.fs-workspace-home__cover-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(252px, 1fr));
  gap: var(--fs-space-2) var(--fs-space-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.fs-workspace-home__cover-list li {
  display: flex;
  align-items: center;
  gap: var(--fs-space-3);
  min-width: 0;
  color: #fff;
  font-size: var(--fs-text-md);
  font-weight: 600;
  line-height: 1.35;
  text-shadow: 0 1px 3px rgb(20 17 13 / 45%);
}

/*
 * Позначка біла й з тінню, бо стоїть на кадрі: зелений `success` на темному
 * фото не видно, а без тіні він зникає на світлій ділянці.
 */
.fs-workspace-home__cover-list li::before {
  display: block;
  flex: 0 0 18px;
  width: 18px;
  height: 18px;
  content: "";
  background: #fff;
  filter: drop-shadow(0 1px 3px rgb(20 17 13 / 45%));
  mask-image: url("../../icons/task/check-circle.svg");
  mask-position: center;
  mask-repeat: no-repeat;
  mask-size: 18px 18px;
  -webkit-mask-image: url("../../icons/task/check-circle.svg");
  -webkit-mask-position: center;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-size: 18px 18px;
}

/*
 * Твердження без плитки. Рамка навколо кожної з шести переваг робила з розділу
 * панель у панелі шість разів; те, що їх шість і що вони окремі, каже волосина
 * зверху — той самий прийом, яким розділені рядки будь-якого списку.
 */
.fs-workspace-home__highlights--flat {
  gap: var(--fs-space-4) var(--fs-space-6);
}

.fs-workspace-home__highlights--flat article {
  padding: var(--fs-space-3) 0 0;
  background: none;
  border: 0;
  border-top: 1px solid var(--fs-color-border-subtle);
  border-radius: 0;
}

/*
 * Сторінка закривається тим самим, чим відкрилась. Тут стоїть одне речення про
 * компанію, тому блок нижчий за обкладинку і не має заголовка: другий h1 у
 * кінці читався б як початок ще однієї сторінки.
 */
.fs-workspace-home__closing {
  min-height: 232px;
}

.fs-workspace-home__closing-copy {
  gap: var(--fs-space-2);
  padding: var(--fs-space-6);
}

.fs-workspace-home__closing-copy p {
  font-size: var(--fs-text-lg);
  font-weight: 600;
}

/*
 * Mobile home: cover.
 *
 * The announcement runs to all four edges of the top of the screen. The assistant
 * remains available over the cover without spending a separate row above it.
 */
.fs-mobile-cover {
  position: relative;
  isolation: isolate;
}

/*
 * Смуга стоїть над усіма шарами обкладинки, а не над одним із них.
 *
 * `z-index: 2` вистачало рівно доти, доки обкладинка була одним кадром. Коли
 * під нею з'явилася колода новин зі своїми шарами — кадр, затемнення, копія,
 * крапки — активний слайд почав перекривати смугу, і знак Farron у правому
 * куті переставав натискатися: палець потрапляв у картку новини. Число тут
 * більше за найглибший шар колоди (`4`), а не «на одиницю більше за сусіда».
 */
.fs-mobile-cover__bar {
  position: absolute;
  z-index: 5;
  top: 0;
  right: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--fs-space-3);
  padding: calc(env(safe-area-inset-top) + 10px) 16px 0;
}

/*
 * Марка компанії на обкладинці.
 *
 * Вона належить саме обкладинці, а не деку: на слайді новини вона стояла б на чужому фото і
 * сперечалася з бейджем «Новини» за той самий верх екрана. Тому вона зникає, щойно дек
 * перемикається з нульового слайда, і повертається разом із ним.
 */
.fs-mobile-cover__brand {
  position: relative;
  isolation: isolate;
  padding: 4px 8px;
  transition: opacity 0.18s ease, visibility 0.18s ease;
}

/*
 * Матова пляма під маркою, розмита по власних краях. Фото за обкладинкою публікує клієнт, тому
 * марці потрібно на чому стояти — але тверда плитка читалася б як другий логотип поверх фото.
 */
.fs-mobile-cover__brand::before {
  position: absolute;
  z-index: -1;
  inset: -6px -10px;
  backdrop-filter: blur(10px);
  content: "";
  mask-image: radial-gradient(ellipse at center, #000 42%, transparent 76%);
  -webkit-mask-image: radial-gradient(ellipse at center, #000 42%, transparent 76%);
}

.fs-mobile-cover__brand img {
  display: block;
  width: auto;
  max-width: 58vw;
  height: 43px;
  object-fit: contain;
}

/*
 * Індекс активного слайда публікує сам дек. Нульовий слайд у цій композиції завжди обкладинка,
 * тому будь-який інший означає новину — і марка йде з екрана разом із обкладинкою.
 */
.fs-mobile-cover:has([data-company-news-index]:not([data-company-news-index="0"])) .fs-mobile-cover__brand {
  opacity: 0;
  visibility: hidden;
}

/*
 * Glass, not a white button: the fill is mostly transparent and the blur behind
 * it is what carries the dark mark over an unpredictable photo.
 */
.fs-mobile-cover__assistant {
  display: grid;
  flex: none;
  place-items: center;
  width: 38px;
  height: 38px;
  background: rgb(255 255 255 / 30%);
  border: 1px solid rgb(255 255 255 / 45%);
  border-radius: var(--fs-radius-lg);
  box-shadow: 0 4px 14px rgb(20 17 13 / 18%);
  backdrop-filter: blur(14px);
}

.fs-mobile-cover__assistant img {
  display: block;
  width: 24px;
  height: 24px;
}

/*
 * Everything below the cover rides on one sheet. Its rounded edge laps over the
 * foot of the photo, which is what says the cover lies behind the page rather
 * than being its first block. Same surface as the canvas, so the corner is only
 * visible where it crosses the image.
 */
.fs-mobile-sheet {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--fs-space-3);
  margin-top: -16px;
  padding: 16px 14px 6px;
  background: var(--fs-color-canvas);
  border-radius: 22px 22px 0 0;
}

/*
 * Personal KPI: the horizontal track shared by the sidebar rail and the mobile
 * home sheet. One card per measure, one measure per screenful of the track.
 */
.fs-workspace-kpis {
  position: relative;
  display: grid;
  gap: var(--fs-space-2);
  min-width: 0;
}

.fs-workspace-kpis__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(360px, 1fr);
  gap: var(--fs-space-3);
  overflow-x: auto;
  padding-bottom: 2px;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
}

.fs-workspace-kpis__track > .fs-mobile-kpi {
  scroll-snap-align: start;
}

/*
 * A row under the track rather than a pill floating on the card. Overlaying it
 * cost every card 42px of bottom padding to keep clear of six dots — a third of
 * the height of a compact card spent on a page indicator.
 */
.fs-workspace-kpis__carousel {
  display: flex;
  justify-content: center;
  align-items: center;
  justify-self: center;
  gap: 4px;
}

.fs-workspace-kpis__dot {
  width: 5px;
  height: 5px;
  padding: 0;
  background: var(--fs-color-border);
  border: 0;
  border-radius: 50%;
  transition: width 0.18s ease, background-color 0.18s ease;
}

.fs-workspace-kpis__dot[aria-selected="true"] {
  width: 12px;
  background: var(--fs-color-text-muted);
  border-radius: var(--fs-radius-pill);
}

.fs-workspace-kpis__dot:focus-visible {
  outline: none;
  box-shadow: var(--fs-focus-ring);
}

.fs-workspace-sidebar-kpis {
  position: relative;
  z-index: 1;
  min-width: 0;
  margin: 0 var(--fs-space-2) var(--fs-space-2);
}

.fs-workspace-sidebar-kpis .fs-workspace-kpis__track {
  grid-auto-columns: 100%;
  gap: 0;
  padding-bottom: 0;
  scrollbar-width: none;
}

.fs-workspace-sidebar-kpis .fs-workspace-kpis__track::-webkit-scrollbar {
  display: none;
}

.fs-workspace-sidebar-kpis .fs-mobile-kpi {
  --fs-kpi-inset: var(--fs-space-3);
  /*
   * The rail is narrower, so a day gets less width — which is why the columns
   * need the height back: at 48px a month of sales read as one low band.
   */
  --fs-kpi-chart-height: 62px;
  --fs-kpi-ring-size: 60px;
  min-height: 128px;
  padding: 10px var(--fs-kpi-inset) var(--fs-space-3);
  border-radius: var(--fs-radius-card);
}

/*
 * The workspace puts its blocks in this container rather than straight into
 * `.fs-page`, so the page rhythm has to be read here too — otherwise the home
 * screen keeps its own spacing while every other page moves.
 *
 * Both defaults stand above the breakpoint that swaps them. A media query has no
 * specificity of its own, so the same selector declared later in the file wins
 * whatever the screen width: with these two at the foot of the stylesheet the
 * phone kept the desktop container and hid the mobile one, and since the desktop
 * blocks are themselves hidden under 760px the home screen came out empty.
 */
.fs-workspace-desktop-content {
  display: grid;
  gap: var(--fs-page-gap);
}

.fs-workspace-mobile-content {
  display: none;
}

@media (max-width: 1199px) {
  .fs-content:has(.fs-workspace-page) {
    padding: 0;
  }

  .fs-workspace-desktop-content {
    display: none;
  }

  .fs-workspace-mobile-content {
    display: block;
    padding: 0;
  }
}

@media (max-width: 900px) {
  .fs-workspace-features {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 600px) {
  .fs-workspace-welcome h2 {
    font-size: 23px;
  }
}

.fs-workspace-sidebar-kpis .fs-workspace-kpis:has(.fs-workspace-kpis__carousel) .fs-mobile-kpi {
  padding-bottom: var(--fs-space-8);
}

.fs-workspace-sidebar-kpis .fs-workspace-kpis__carousel {
  position: absolute;
  right: 0;
  bottom: var(--fs-space-2);
  left: 0;
  z-index: 1;
}

/* Lying on the card, the dots take the card's own scale of white. */
.fs-workspace-sidebar-kpis .fs-workspace-kpis__dot {
  background: rgb(255 255 255 / 34%);
}

.fs-workspace-sidebar-kpis .fs-workspace-kpis__dot[aria-selected="true"] {
  background: rgb(255 255 255 / 88%);
}

/* The rail is 260px wide: every figure steps down one size, none of them wrap. */
.fs-workspace-sidebar-kpis .fs-mobile-kpi__value > strong {
  font-size: 30px;
}

.fs-workspace-sidebar-kpis .fs-mobile-kpi__amount {
  font-size: var(--fs-text-xl);
}

.fs-workspace-sidebar-kpis .fs-mobile-kpi__counters dd {
  font-size: var(--fs-text-lg);
}

/* The whole rail is navigation already; a second way in would only repeat it. The
   column goes with it: kept, it ended the chart a gap short of the card's inset. */
.fs-workspace-sidebar-kpis .fs-mobile-kpi__destination {
  display: none;
}

.fs-workspace-sidebar-kpis .fs-mobile-kpi__figure {
  grid-template-columns: minmax(0, 1fr);
}

/*
 * A KPI card is an instrument panel, and the only accent surface on either
 * screen. Its anatomy is fixed: a head that names the measure and scopes it,
 * then one figure that answers it. There are four figures — plan, risk,
 * composition and outcome — and each draws exactly the fields it carries.
 *
 * A surface is the variables below and nothing more, so a new measure is a
 * palette rather than a second copy of the card. Every surface is deep and low
 * in chroma: the figure is what has to carry, and a loud fill puts the reader's
 * eye on the card instead of on the number.
 */
.fs-mobile-kpi {
  --fs-kpi-inset: 15px;
  --fs-kpi-start: #1a5f99;
  --fs-kpi-end: #093962;
  /*
   * One light and nothing else. Every pattern tried here — hatch, grid, dots —
   * was something the eye kept trying to resolve on a card whose whole job is a
   * single number. Surfaces are told apart by their colour and by which corner
   * the light falls from.
   */
  --fs-kpi-texture: radial-gradient(130% 100% at 88% -22%, rgb(255 255 255 / 12%), transparent 64%);
  --fs-kpi-accent: var(--fs-palette-22);
  /* Where the pace lands: the same accent, pale, so it reads as "not yet". */
  --fs-kpi-forecast-fill: color-mix(in srgb, var(--fs-kpi-accent) 36%, transparent);
  --fs-kpi-shadow: 0 10px 26px rgb(8 44 76 / 30%);
  --fs-kpi-label: rgb(255 255 255 / 66%);
  --fs-kpi-chart-height: 62px;
  --fs-kpi-ring-size: 72px;
  position: relative;
  isolation: isolate;
  display: grid;
  /* The track gives every card the height of the tallest; the figure takes what the head leaves. */
  grid-template-rows: auto 1fr;
  gap: 9px;
  padding: 11px var(--fs-kpi-inset) 13px;
  overflow: hidden;
  color: #fff;
  background:
    var(--fs-kpi-texture),
    linear-gradient(156deg, var(--fs-kpi-start) 0%, var(--fs-kpi-end) 100%);
  border-radius: 16px;
  /* The top edge catches light the way a physical panel does; without it a flat
     dark fill reads as a hole in the page rather than as a surface on it. */
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 14%), var(--fs-kpi-shadow);
}

/*
 * Operational counts — requests, repairs — are a different measurement, so they
 * take the identity slate of the workspace background instead of the action
 * blue. Two cards must never be told apart only by what is written on them.
 */
.fs-mobile-kpi--operations {
  --fs-kpi-start: #1e5b62;
  --fs-kpi-end: #123742;
  --fs-kpi-texture: radial-gradient(120% 95% at 10% -18%, rgb(255 255 255 / 11%), transparent 62%);
  --fs-kpi-accent: #9fd6c4;
  --fs-kpi-shadow: 0 10px 26px rgb(8 35 44 / 32%);
}

/*
 * A risk speaks in danger only on a day it grew. A red card every day, debt
 * shrinking or not, stopped meaning anything exactly where the product needs a
 * signal; on a calm day the same reading lies on graphite and keeps its rose
 * line, so it is still recognisably the debt.
 */
.fs-mobile-kpi--risk {
  --fs-kpi-start: var(--fs-color-danger);
  --fs-kpi-end: var(--fs-color-danger-hover);
  --fs-kpi-texture: none;
  --fs-kpi-accent: var(--fs-color-danger-line);
  --fs-kpi-shadow: 0 10px 26px color-mix(in srgb, var(--fs-color-danger-hover) 55%, transparent);
}

.fs-mobile-kpi--risk-calm {
  --fs-kpi-start: #3b4148;
  --fs-kpi-end: #22272c;
  --fs-kpi-texture: radial-gradient(120% 95% at 88% -20%, rgb(255 255 255 / 9%), transparent 62%);
  --fs-kpi-accent: var(--fs-color-danger-line);
  --fs-kpi-shadow: 0 10px 26px rgb(20 24 28 / 34%);
}

/* ── Head: what is measured, and over what period ────────────────────────── */

.fs-mobile-kpi__head {
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--fs-space-2);
  padding-bottom: 9px;
}

/*
 * A rule that starts at the name and is gone before the right edge. It divides
 * the head from the figure where the reading starts; carried all the way across
 * it becomes an underline under the period switcher, which divides nothing.
 */
.fs-mobile-kpi__head::after {
  position: absolute;
  right: calc(var(--fs-kpi-inset) * -1);
  bottom: 0;
  left: calc(var(--fs-kpi-inset) * -1);
  height: 1px;
  background: linear-gradient(90deg, rgb(255 255 255 / 17%) 0%, rgb(255 255 255 / 0%) 52%);
  content: "";
}

.fs-mobile-kpi__title {
  margin: 0;
  color: rgb(255 255 255 / 88%);
  font-size: var(--fs-text-xs);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

/*
 * The time of the data is all the card says about its age, stale snapshot
 * included: the reader judges the time, and a hedge beside it only taught them
 * to doubt every card.
 */
.fs-mobile-kpi__freshness {
  margin: 3px 0 0;
  color: rgb(255 255 255 / 52%);
  font-size: 10px;
  letter-spacing: 0.01em;
}

/*
 * Scope, not navigation: two words, and the current one is simply the brighter
 * one. A solid white plate here was the loudest thing on a card whose subject is
 * a number — a period switcher does not outrank the figure it scopes.
 */
.fs-mobile-kpi__periods {
  display: flex;
  flex: none;
  gap: 3px;
  margin-top: -1px;
}

.fs-mobile-kpi__period {
  padding: 3px 8px;
  color: rgb(255 255 255 / 52%);
  background: transparent;
  border: 0;
  border-radius: var(--fs-radius-pill);
  font: inherit;
  font-size: var(--fs-text-xs);
  font-weight: 600;
  cursor: pointer;
  transition: color 0.14s ease, background-color 0.14s ease;
}

@media (hover: hover) {
  .fs-mobile-kpi__period:hover {
    color: rgb(255 255 255 / 82%);
  }
}

.fs-mobile-kpi__period[aria-selected="true"] {
  color: #fff;
  background: rgb(255 255 255 / 14%);
}

.fs-mobile-kpi__period:focus-visible {
  outline: 2px solid rgb(255 255 255 / 76%);
  outline-offset: 1px;
}

/* ── Figure: one reading, and the way out to its detail ──────────────────── */

/*
 * Two columns, so a chart and the link to the feature share the closing line.
 * A row of its own under the card cost a seventh of the block to say what the
 * arrow already says. Everything else spans the card.
 *
 * Every figure is a lead — the reading it opens with — and a closing line. The
 * lead's row takes whatever height the card has spare, so a shorter figure keeps
 * its reading on top and its closing line on the card's bottom edge, level with
 * the neighbour's history, instead of leaving the spare height under it.
 */
.fs-mobile-kpi__figure {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: 1fr;
  align-items: center;
  gap: 7px 10px;
}

.fs-mobile-kpi__figure > * {
  grid-column: 1 / -1;
}

.fs-mobile-kpi__figure > :first-child {
  align-self: start;
}

/* A lead of several parts — a number, its scale, its legend — keeps them together. */
.fs-mobile-kpi__lead {
  display: grid;
  gap: 7px;
  min-width: 0;
}

.fs-mobile-kpi__figure > .fs-mobile-kpi__chart {
  grid-column: 1;
}

.fs-mobile-kpi__figure > .fs-mobile-kpi__destination {
  grid-column: 2;
}

/* Немає куди вести — немає й другої колонки: порожня забирала в графіка проміжок праворуч. */
.fs-mobile-kpi__figure:not(:has(> .fs-mobile-kpi__destination)) {
  grid-template-columns: minmax(0, 1fr);
}

/* `display` above would otherwise reveal the periods the switcher has hidden. */
.fs-mobile-kpi__figure[hidden] {
  display: none;
}

/*
 * The row wraps. A figure is never broken across lines, so on a narrow card the
 * side reading takes a line of its own instead of pushing itself off the card.
 */
.fs-mobile-kpi__value {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 9px;
  margin: 0;
}

.fs-mobile-kpi__value > strong {
  font-size: 36px;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 0.95;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* The unit names the number; it never sets its size. */
.fs-mobile-kpi__unit {
  color: var(--fs-kpi-label);
  font-size: var(--fs-text-sm);
  font-weight: 500;
}

/* A second, smaller reading of the same line: a share of the plan, an average. */
.fs-mobile-kpi__side {
  margin-left: auto;
  color: var(--fs-kpi-label);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.fs-mobile-kpi__side strong {
  color: #fff;
  font-size: var(--fs-text-lg);
  font-weight: 600;
}

/*
 * Money the card counts as done takes the surface accent: the one colour it
 * spends. On a plan the ring fills in the same colour, so the arc and the
 * amount read as one statement.
 */
.fs-mobile-kpi__money {
  color: var(--fs-kpi-accent);
}

/* ── Plan: the amount leads, the ring captions it ───────────────────────── */

.fs-mobile-kpi__plan {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 14px;
}

/*
 * The ring is the whole plan, drawn once: the filled arc is sold, the pale arc
 * is where the pace lands, the white mark is how much of the period is worked.
 * The share only captions the amount beside it, so it stays small inside.
 */
.fs-mobile-kpi__ring {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--fs-kpi-ring-size);
  aspect-ratio: 1;
}

.fs-mobile-kpi__ring::before {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    var(--fs-kpi-accent) 0 calc(var(--fs-kpi-achieved) * 1%),
    var(--fs-kpi-forecast-fill) 0 calc(var(--fs-kpi-forecast) * 1%),
    rgb(255 255 255 / 14%) 0
  );
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 7px), #000 calc(100% - 6.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 7px), #000 calc(100% - 6.5px));
  content: "";
}

/* The pace mark crosses the ring a little on both sides, so it reads on any arc. */
.fs-mobile-kpi__ring--pace::after {
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  background: conic-gradient(from calc(var(--fs-kpi-pace) * 3.6deg - 1.5deg), #fff 0 3deg, transparent 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 15px), #000 calc(100% - 14.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 15px), #000 calc(100% - 14.5px));
  content: "";
}

.fs-mobile-kpi__ring-value {
  position: relative;
  color: rgb(255 255 255 / 90%);
  font-size: var(--fs-text-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/*
 * The text of a reading: the amount, what it is measured against, and two
 * labelled readouts. The plan sets it beside its ring and the risk on its own,
 * so the two cards come out one height by construction rather than one of them
 * being trimmed to fit the other.
 */
.fs-mobile-kpi__reading {
  display: grid;
  gap: 1px;
  min-width: 0;
  line-height: 1.25;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.fs-mobile-kpi__of {
  color: var(--fs-kpi-label);
  font-size: 12px;
  font-weight: 500;
}

/*
 * The amount and its readouts are two readings, and the gap between them says
 * so: above it the money of today, under it the two figures that say where it is
 * going — the forecast and the days, or the moves of a debt — each named by its
 * own label rather than by a word inside the line.
 */
.fs-mobile-kpi__readouts {
  display: grid;
  gap: 1px;
  margin: 5px 0 0;
  font-variant-numeric: tabular-nums;
}

.fs-mobile-kpi__readouts > div {
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.fs-mobile-kpi__readouts dt {
  color: var(--fs-kpi-label);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.fs-mobile-kpi__readouts dd {
  margin: 0;
  color: rgb(255 255 255 / 86%);
  font-size: 11.5px;
  font-weight: 600;
}

.fs-mobile-kpi__amount {
  margin-bottom: 2px;
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.05;
}

/* ── Risk: the amount, its movement and its level over the month ─────────── */

/* Arrow plus signed value carry the direction; the colour only repeats it. */
.fs-mobile-kpi__readouts [data-trend-positive="true"] dd {
  color: #cfeed8;
}

.fs-mobile-kpi__readouts [data-trend-positive="false"] dd {
  color: #ffd3cc;
}

/* ── Bar and scale ───────────────────────────────────────────────────────── */

/*
 * One thin line the width of the card. It is a scale, not a component: the
 * reading is the number above it, and the line only says where that number
 * stands. One fixed colour — it measures rather than grades.
 */
.fs-mobile-kpi__bar {
  height: 4px;
  overflow: hidden;
  background: rgb(255 255 255 / 14%);
  border-radius: var(--fs-radius-pill);
}

.fs-mobile-kpi__bar span {
  display: block;
  height: 100%;
  background: var(--fs-kpi-accent);
  border-radius: inherit;
}

/*
 * The share and its base are one sentence, not two edges of the card. Pushed
 * apart they read as two separate figures and the eye has to travel the full
 * width to pair them; together they are the caption of the number above.
 */
.fs-mobile-kpi__scale {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 7px;
  margin: -2px 0 0;
  color: rgb(255 255 255 / 84%);
  font-size: var(--fs-text-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.fs-mobile-kpi__scale span + span {
  color: var(--fs-kpi-label);
  font-weight: 500;
}

.fs-mobile-kpi__scale span + span::before {
  margin-right: 7px;
  color: rgb(255 255 255 / 32%);
  content: "·";
}

/* ── History: the second reading of the card ────────────────────────────── */

/*
 * Given room to be read: the chart, and under its ends the two dates that bound
 * it. A heading over it would be a sentence explaining a picture that explains
 * itself; the full wording stays in the group's aria-label.
 */
.fs-mobile-kpi__chart {
  display: grid;
  gap: 3px;
  min-width: 0;
  margin-top: 2px;
}

.fs-mobile-kpi__chart--placeholder {
  visibility: hidden;
  pointer-events: none;
}

.fs-mobile-kpi__chart-scale {
  display: flex;
  justify-content: space-between;
  gap: var(--fs-space-2);
  margin: 0;
  color: rgb(255 255 255 / 52%);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.04em;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* The dates under the columns bound the drawn days, not the room left for the rest of the month.
   Without the counts (the placeholder) the width is invalid and falls back to auto. */
.fs-mobile-kpi__columns + .fs-mobile-kpi__chart-scale {
  width: calc(var(--fs-kpi-days) / var(--fs-kpi-slots) * 100%);
  min-width: max-content;
  max-width: 100%;
}

/*
 * Sales are a flow, so every working day is a column; its height is a share of
 * the tallest on the scale, and the dashed line is the daily norm. Today is the
 * column still being filled, so it takes the full accent.
 */
.fs-mobile-kpi__columns {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: var(--fs-kpi-chart-height);
  border-bottom: 1px solid rgb(255 255 255 / 22%);
}

/*
 * A column is never wider than one work day of the period. The chart keeps room
 * for the whole month, so its first days read as the start of it rather than
 * as one slab stretched over the card.
 */
.fs-mobile-kpi__columns > span {
  flex: 1 1 0;
  min-width: 0;
  max-width: calc((100% - (var(--fs-kpi-slots, 1) - 1) * 2px) / var(--fs-kpi-slots, 1));
  height: max(2px, calc(var(--fs-kpi-level) * 1%));
  background: color-mix(in srgb, var(--fs-kpi-accent) 70%, transparent);
  border-radius: 2px 2px 0 0;
}

.fs-mobile-kpi__columns > span:last-child {
  background: var(--fs-kpi-accent);
}

.fs-mobile-kpi__columns--norm::after {
  position: absolute;
  right: 0;
  bottom: calc(var(--fs-kpi-norm) * 1%);
  left: 0;
  border-top: 1px dashed rgb(255 255 255 / 62%);
  content: "";
  pointer-events: none;
}

/*
 * A debt is a level, not a flow: columns from zero came out the same height
 * every day and showed no movement at all. The line stands between its own
 * lowest and highest value, and the dot is today.
 */
.fs-mobile-kpi__line {
  position: relative;
  height: var(--fs-kpi-chart-height);
}

.fs-mobile-kpi__line svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.fs-mobile-kpi__line-area {
  fill: rgb(255 255 255 / 10%);
}

.fs-mobile-kpi__line-path {
  fill: none;
  stroke: var(--fs-kpi-accent);
  stroke-width: 1.6;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.fs-mobile-kpi__line-end {
  position: absolute;
  width: 7px;
  height: 7px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 0 0 3px rgb(255 255 255 / 22%);
  transform: translate(-50%, -50%);
}

/* ── Composition: the whole once, one bar, a legend ─────────────────────── */

/* The part carries its meaning in data-tone, like every other state in Stoneware. */
.fs-mobile-kpi [data-tone="neutral"] {
  --fs-kpi-part: rgb(255 255 255 / 38%);
}

.fs-mobile-kpi [data-tone="info"] {
  --fs-kpi-part: var(--fs-kpi-accent);
}

.fs-mobile-kpi [data-tone="success"] {
  --fs-kpi-part: #cfeed8;
}

.fs-mobile-kpi [data-tone="warning"] {
  --fs-kpi-part: #ffd68c;
}

/* A flagged part lies inside the state before it, so it is hatched, not solid. */
.fs-mobile-kpi [data-flagged="true"] {
  --fs-kpi-part: repeating-linear-gradient(135deg, #ffd68c 0 2px, rgb(255 214 140 / 45%) 2px 4px);
}

.fs-mobile-kpi__composition {
  display: flex;
  gap: 2px;
  height: 10px;
}

.fs-mobile-kpi__composition > span {
  flex-basis: 0;
  min-width: 3px;
  background: var(--fs-kpi-part);
  border-radius: 3px;
}

.fs-mobile-kpi__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin: 0;
  padding: 0;
  color: rgb(255 255 255 / 76%);
  font-size: 11.5px;
  list-style: none;
  font-variant-numeric: tabular-nums;
}

.fs-mobile-kpi__legend li {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.fs-mobile-kpi__legend li::before {
  flex: none;
  width: 10px;
  height: 8px;
  background: var(--fs-kpi-part);
  border-radius: 2px;
  content: "";
}

/* Values that are not parts of the whole close the card under a hairline. */
.fs-mobile-kpi__facts {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 4px 10px;
  margin: 0;
  padding-top: 8px;
  color: rgb(255 255 255 / 62%);
  border-top: 1px solid rgb(255 255 255 / 14%);
  font-size: var(--fs-text-xs);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.fs-mobile-kpi__legend strong,
.fs-mobile-kpi__facts strong {
  color: #fff;
  font-weight: 600;
}

/* A value that leads to its records: the same words, underlined as a way in. */
.fs-mobile-kpi__link {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: rgb(255 255 255 / 35%);
  text-underline-offset: 3px;
}

@media (hover: hover) {
  .fs-mobile-kpi__link:hover {
    text-decoration-color: currentcolor;
  }
}

.fs-mobile-kpi__link:focus-visible {
  outline: 2px solid rgb(255 255 255 / 76%);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ── Outcome: the money, its share of the base, the counters behind it ──── */

.fs-mobile-kpi__counters {
  display: flex;
  justify-content: space-between;
  gap: var(--fs-space-2);
  margin: 0;
  padding-top: 8px;
  border-top: 1px solid rgb(255 255 255 / 14%);
}

.fs-mobile-kpi__counters > div {
  display: flex;
  flex-direction: column-reverse;
  min-width: 0;
}

.fs-mobile-kpi__counters dt,
.fs-mobile-kpi__counters dd {
  margin: 0;
}

.fs-mobile-kpi__counters dt {
  margin-top: 2px;
  color: var(--fs-kpi-label);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.fs-mobile-kpi__counters dd {
  font-size: 18px;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* The tone belongs to the figure and its label always repeats it in words. */
.fs-mobile-kpi__counter--info dd { color: #cfe6ff; }
.fs-mobile-kpi__counter--warning dd { color: #ffe3b0; }
.fs-mobile-kpi__counter--success dd { color: #cfeed8; }

/* ── Closing line and placeholder ────────────────────────────────────────── */

.fs-mobile-kpi__destination {
  justify-self: end;
  align-self: end;
  color: rgb(255 255 255 / 78%);
  font-size: var(--fs-text-xs);
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
}

@media (hover: hover) {
  .fs-mobile-kpi__destination:hover {
    color: #fff;
  }
}

.fs-mobile-kpi__destination:focus-visible {
  outline: 2px solid rgb(255 255 255 / 76%);
  outline-offset: 3px;
  border-radius: 3px;
}

/*
 * The placeholder takes the surface of the card it will become. A white plate
 * here made the screen flash a panel that is about to be replaced by a dark one.
 */
.fs-mobile-kpi-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--fs-space-2);
  min-height: 78px;
  padding: 0 var(--fs-space-4);
  color: rgb(255 255 255 / 78%);
  background: linear-gradient(156deg, #1a5f99 0%, #093962 100%);
  border-radius: 16px;
  font-size: var(--fs-text-sm);
}

@media (max-width: 1100px) {
  .fs-workspace-home__hero {
    grid-template-columns: 1fr;
  }

  .fs-workspace-home__cover {
    min-height: 320px;
  }

  .fs-workspace-home__closing {
    min-height: 196px;
  }

  .fs-workspace-home__cover--section {
    min-height: 300px;
  }

  .fs-workspace-home__hero-media {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .fs-workspace-home__highlights {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .fs-workspace-home__gallery {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Narrow: the photo becomes a band under the copy rather than a third column. */
  .fs-workspace-home__section:has(.fs-workspace-home__section-content figure) {
    grid-template-columns: 1fr;
    grid-template-rows: none;
  }

  .fs-workspace-home__section-content figure {
    grid-column: 1;
    grid-row: auto;
    height: 170px;
  }

  /* A captioned photo sizes its own rows: a fixed height would eat the sentence. */
  .fs-workspace-home__section-content figure:has(figcaption) {
    height: auto;
    grid-template-rows: 170px auto;
  }
}

@media (max-width: 760px) {
  .fs-workspace-home {
    display: none;
  }

  /*
   * Картки йдуть як банківські (рішення 2026-10-27): поточна стоїть по центру, а з обох боків
   * виглядає по 12px сусідньої — так видно, що їх кілька, ще до того, як прочитано крапки. Доріжка
   * виходить за поля аркуша на його ж 14px і повертає їх як внутрішній відступ 24px, тому перша
   * картка стоїть на 10px глибше за край аркуша, а наступна виглядає з-за правого краю екрана.
   */
  .fs-mobile-sheet .fs-workspace-kpis__track {
    grid-auto-columns: 100%;
    gap: 12px;
    overflow-x: auto;
    margin-inline: -14px;
    padding-inline: 24px;
    padding-bottom: 4px;
    scroll-padding-inline: 24px;
    scrollbar-width: none;
  }

  .fs-mobile-sheet .fs-workspace-kpis__track > .fs-mobile-kpi {
    scroll-snap-align: center;
  }

  .fs-mobile-sheet .fs-workspace-kpis__track::-webkit-scrollbar {
    display: none;
  }

  .fs-mobile-sheet .fs-workspace-kpis {
    gap: var(--fs-space-1);
  }

  /*
   * The card lies inside the shared sheet rather than floating over it, so it
   * keeps its surface and drops the lift.
   *
   * І віддає чверть висоти. Картка займала перший екран головної майже цілком, а
   * її вміст — назва, число й ряд стовпчиків — стільки місця не вимагає: висоту
   * тримали поля, просвіти між рядами та кегль, узятий «щоб було видно
   * здалеку». Тепер число лишається найбільшим на екрані, але не єдиним, що на
   * ньому вміщається; історія з 62px спускається до 42px і зберігає форму, бо
   * читають у ній не значення дня, а напрямок.
   */
  .fs-mobile-sheet .fs-mobile-kpi {
    --fs-kpi-chart-height: 42px;
    gap: 6px;
    padding: 8px 14px 10px;
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 14%);
  }

  .fs-mobile-sheet .fs-mobile-kpi__head {
    padding-bottom: 5px;
  }

  .fs-mobile-sheet .fs-mobile-kpi__freshness {
    margin-top: 2px;
  }

  .fs-mobile-sheet .fs-mobile-kpi__period {
    padding: 2px 10px;
  }

  /* A phone reads the figure from further away than a desktop rail does. */
  .fs-mobile-sheet .fs-mobile-kpi__value > strong {
    font-size: 30px;
  }

  /*
   * The switcher belongs to the card it switches, so it lies on it. A row of its
   * own under the track spent a band of the home screen on six dots and pushed
   * the next block down by more than the dots are worth.
   */
  .fs-mobile-sheet .fs-workspace-kpis:has(.fs-workspace-kpis__carousel) .fs-mobile-kpi {
    padding-bottom: 19px;
  }

  .fs-mobile-sheet .fs-workspace-kpis__carousel {
    position: absolute;
    right: 0;
    bottom: 7px;
    left: 0;
    z-index: 1;
  }

  .fs-mobile-sheet .fs-workspace-kpis__dot {
    background: rgb(255 255 255 / 34%);
  }

  .fs-mobile-sheet .fs-workspace-kpis__dot[aria-selected="true"] {
    background: rgb(255 255 255 / 88%);
  }
}

/* Narrow phones: a smaller ring leaves the amount beside it the width it needs. */
@media (max-width: 340px) {
  .fs-mobile-kpi {
    --fs-kpi-ring-size: 60px;
  }
}

/*
 * The mobile home screen is a stack of titled blocks: the announcement, quick
 * access, then the sections. The title is what makes the screen readable —
 * without it the tiles and the list run together as one undifferentiated wall.
 */
.fs-mobile-home-block {
  display: grid;
  gap: var(--fs-space-2);
}

/* A structural label above the list, not a page title competing with it. */
.fs-mobile-home-heading {
  margin: 0;
  padding: 0 var(--fs-space-1);
  color: var(--fs-color-text-muted);
  font-size: var(--fs-text-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/*
 * Named tiles, the whole row at once: four destinations is the profile maximum,
 * so one row holds the entire set and the screen spends one band on it instead
 * of two. The icon identifies, the label names.
 */
.fs-quick-access {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}

.fs-quick-access-card {
  display: grid;
  align-content: start;
  justify-items: center;
  gap: 5px;
  min-height: 76px;
  padding: 10px 4px 8px;
  background: var(--fs-color-surface);
  border: 1px solid transparent;
  border-radius: 14px;
  box-shadow: var(--fs-shadow-md);
}

.fs-quick-access-card:active {
  background: var(--fs-color-surface-hover);
}

/*
 * The destination names itself; the section it lives in is not news on the tile.
 * Long Ukrainian labels wrap rather than truncate — the name is what the tile is
 * for, and a clipped one costs the tile its purpose.
 */
.fs-quick-access-card__text {
  min-width: 0;
  color: var(--fs-color-text);
  font-size: 9px;
  font-weight: 600;
  line-height: 1.15;
  text-align: center;
  overflow-wrap: anywhere;
}

/*
 * The icons are client-owned artwork and already carry their own colour. They
 * are shown as they are on desktop navigation — no ring, no inner highlight:
 * an outline around a coloured pictogram only fences it in.
 */
.fs-mobile-navigation-icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  box-shadow: none;
}

@media (max-width: 1100px) and (min-width: 761px) {
  .fs-summary__row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .fs-summary__item:nth-child(odd) {
    border-left-color: var(--fs-color-border-subtle);
  }

  .fs-summary__item:nth-child(even) {
    border-left-color: var(--fs-color-border-subtle);
  }

  .fs-summary__item:nth-child(n + 3) {
    border-top-color: var(--fs-color-border-subtle);
  }
}

@media (max-width: 760px) {
  .fs-filters-grid {
    grid-template-columns: 1fr;
  }

  .fs-filters-actions {
    align-items: center;
    justify-content: flex-end;
    flex-direction: row;
    flex-wrap: wrap;
  }

  .fs-result-pagination {
    justify-content: space-between;
    width: 100%;
  }

  .fs-datalist--responsive .fs-datalist__head {
    display: none;
  }

  .fs-datalist--responsive .fs-datalist__row {
    min-height: 0;
    padding: var(--fs-space-3);
  }
}

/* Section artwork is already a complete client-owned pictogram. Semantic
   navigation tones must not turn its wrapper into a coloured square. */
.fs-mobile-menu-sections .fs-mobile-navigation-icon--section {
  background: transparent;
  border: 0;
  box-shadow: none;
}

/*
 * One size step up from the desktop icon: on a phone the pictogram is read at
 * arm's length and is the fastest part of the row to recognise.
 */
.fs-mobile-navigation-icon--quick {
  width: 36px;
  height: 36px;
}

.fs-mobile-navigation-icon--section {
  width: 30px;
  height: 30px;
}

.fs-mobile-navigation-icon--item {
  width: 28px;
  height: 28px;
}

.fs-mobile-navigation-icon img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.fs-mobile-menu-sections {
  display: grid;
  gap: 0;
  overflow: hidden;
  background: var(--fs-color-surface);
  border-radius: 16px;
  box-shadow: var(--fs-shadow-md);
}

/*
 * The hairline starts where the labels start, not at the card edge: it separates
 * two rows of the same list, and running it under the icon column would cut the
 * card into strips instead.
 */
.fs-mobile-menu-group:not(:last-child)::after {
  display: block;
  height: 1px;
  margin-left: 59px;
  background: var(--fs-color-border-subtle);
  content: "";
}

/*
 * A destination row, not a label: sentence case at reading size, because the
 * uppercase tracking made every section shout and cost the row its scan value.
 */
.fs-mobile-menu-group > summary {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  min-height: 60px;
  padding: 10px 15px;
  color: var(--fs-color-text);
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
}

@media (hover: hover) {
  .fs-mobile-menu-group > summary:hover {
    background: var(--fs-color-surface-hover);
  }
}

/* Points right when closed and down when open: the same chevron as the row list. */
.fs-mobile-menu-group > summary::after {
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--fs-color-text-muted);
  border-bottom: 2px solid var(--fs-color-text-muted);
  content: "";
  transform: rotate(-45deg);
  transition: transform 0.16s ease;
}

.fs-mobile-menu-group[open] > summary::after {
  transform: rotate(45deg) translateY(-2px);
}

.fs-mobile-menu-group[open] > summary {
  color: var(--fs-color-primary-text);
}

/*
 * Children of the section, not a separate list: a guide rule ties them to the
 * row above and a modest indent keeps them in the reading column. The old inset
 * pushed them past the middle of the screen, and the warm fill under each one
 * read as "selected" — the tone the brand book reserves for the current place.
 */
.fs-mobile-menu-links {
  gap: 0;
  margin: 0 12px 10px 24px;
  padding-left: 10px;
  border-left: 2px solid var(--fs-color-primary-line);
}

/* Author layout must not override the browser's closed-details hiding. Without
   the explicit states, the last permitted child link can escape as a clipped
   focusable tile underneath the fixed mobile bar. */
.fs-mobile-menu-group:not([open]) > .fs-mobile-menu-links {
  display: none;
}

.fs-mobile-menu-group[open] > .fs-mobile-menu-links {
  display: grid;
}

.fs-mobile-menu-links a {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 42px;
  padding: 6px 10px;
  color: var(--fs-color-text);
  background: transparent;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
}

@media (hover: hover) {
  .fs-mobile-menu-links a:hover {
    background: var(--fs-color-surface-hover);
  }
}

/* Narrow phones: three destinations per row before labels wrap excessively. */
@media (max-width: 339px) {
  .fs-quick-access {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
