/* ==========================================================================
   Arkost SPA (Darkmage engine) - typography layer
   --------------------------------------------------------------------------
   Load order: this file MUST be linked after the inline <style> blocks in
   demo-frontend/index.html, immediately before </head>:

       <link rel="stylesheet" href="typography.css" />

   Scope: typography only. No colours, backgrounds, borders, spacing, motion
   or focus styles are declared here. Selectors are single-class wherever
   possible and rely on source order (not !important) to win over the inline
   styles. The only exceptions are the legacy inline font-size floor at the
   end of this file, which is intentionally temporary.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* UI stack. Every family below ships with Cyrillic and Latin coverage on
     the platforms where it is the system default; no network font is used. */
  --font-ui: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Noto Sans", "PT Sans", "Helvetica Neue", Arial, sans-serif;

  /* Distinct code stack. Ligatures/calt are disabled in section 5. */
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Code",
    "Cascadia Mono", "Roboto Mono", "JetBrains Mono", "Fira Code", Consolas,
    "Liberation Mono", Menlo, monospace;

  /* Scale. 1rem = 16px; rem keeps the scale responsive to browser settings. */
  --type-display: clamp(1.75rem, 1.5rem + 1.4vw, 2rem);      /* 28 -> 32 */
  --type-title: clamp(1.375rem, 1.2rem + 0.7vw, 1.5rem);     /* 22 -> 24 */
  --type-heading: clamp(1.0625rem, 1rem + 0.3vw, 1.125rem);  /* 17 -> 18 */
  --type-subheading: 1rem;                                   /* 16 */
  --type-body: 0.9375rem;                                    /* 15, 16 mobile */
  --type-small: 0.875rem;                                    /* 14 */
  --type-meta: 0.8125rem;                                    /* 13 */
  --type-micro: 0.75rem;                                     /* 12 minimum */
  --type-code: 0.8125rem;                                    /* 13 */

  /* Unitless line heights keep vertical rhythm when text is resized. */
  --leading-display: 1.05;
  --leading-title: 1.2;
  --leading-heading: 1.3;
  --leading-subheading: 1.35;
  --leading-body: 1.55;
  --leading-small: 1.5;
  --leading-meta: 1.45;
  --leading-micro: 1.35;
  --leading-code: 1.65;

  /* Four usable weights only; no 300/350 or synthetic ultra-light text. */
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  --tracking-display: -0.02em;
  --tracking-title: -0.012em;
  --tracking-heading: -0.006em;
  --tracking-caps: 0.05em;

  --numeric-tabular: tabular-nums lining-nums;
}

/* --------------------------------------------------------------------------
   2. Base, form controls, theme rendering
   -------------------------------------------------------------------------- */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  font-family: var(--font-ui);
  font-size: var(--type-body);
  line-height: 1.45;
  font-kerning: normal;
}

/* Rendering differs on dark vs light canvases. These are the only theme-
   specific declarations: colours and contrast stay owned by index.html. */
body:not(.light) {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body.light {
  -webkit-font-smoothing: auto;
  -moz-osx-font-smoothing: auto;
}

button {
  font-family: var(--font-ui);
  font-size: var(--type-small);
  line-height: 1.2;
}

.btn,
.auth-tab {
  font-size: var(--type-small);
}

.btn.small {
  font-size: var(--type-micro);
}

input,
select,
textarea {
  font-family: var(--font-ui);
  font-size: var(--type-body);
  line-height: 1.4;
}

.field input[type="text"],
.field input[type="email"],
.field input[type="password"],
.modal input,
.new-ws input,
.question-own {
  font-size: var(--type-body);
  line-height: 1.4;
}

/* --------------------------------------------------------------------------
   3. Headings and display text
   -------------------------------------------------------------------------- */
h1,
h2,
h3,
h4,
h5,
h6 {
  font-weight: var(--weight-bold);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  text-wrap: balance;
}

h1 {
  font-size: var(--type-title);
  line-height: var(--leading-title);
  letter-spacing: var(--tracking-title);
}

h2 {
  font-size: var(--type-heading);
}

h3 {
  font-size: var(--type-subheading);
}

h4,
h5,
h6 {
  font-size: var(--type-body);
}

/* Existing explicit heading classes need the same treatment because their
   class selectors otherwise win over the element rules above. */
.view-title,
.ws-title,
.auth-logo,
.empty-start h3 {
  font-size: var(--type-title);
  line-height: var(--leading-title);
  letter-spacing: var(--tracking-title);
  font-weight: var(--weight-bold);
}

.chat-title,
.modal h3,
.tariff-card h3 {
  font-size: var(--type-heading);
  line-height: var(--leading-heading);
}

.panel-title,
.fm-title,
.fm-state h3,
.fm-preview-fallback h3,
.fm-drop-overlay strong {
  font-size: var(--type-subheading);
  line-height: var(--leading-subheading);
  font-weight: var(--weight-semibold);
}

.fm-props-name {
  font-size: var(--type-body);
  line-height: 1.35;
  font-weight: var(--weight-semibold);
}

.tariff-price {
  font-size: var(--type-display);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  font-weight: var(--weight-bold);
}

.tariff-price sup {
  font-size: 0.5em;
  line-height: 1;
}

.brand {
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-title);
}

/* --------------------------------------------------------------------------
   4. Body copy, labels, metadata, badges
   -------------------------------------------------------------------------- */
p {
  text-wrap: pretty;
}

.auth-sub,
.view-sub {
  font-size: var(--type-small);
  line-height: var(--leading-small);
}

.msg,
.modal p,
.empty,
.empty-start p {
  font-size: var(--type-body);
  line-height: var(--leading-body);
}

.msg {
  overflow-wrap: break-word;
}

.form-note,
.form-error,
.checkbox-row,
.tech-details {
  font-size: var(--type-meta);
  line-height: var(--leading-meta);
}

.approval-card,
.tool-card {
  font-size: var(--type-small);
  line-height: var(--leading-small);
}

.field label {
  font-size: var(--type-meta);
  line-height: 1.35;
  font-weight: var(--weight-medium);
}

.composer-row label,
.password-toggle,
.small {
  font-size: var(--type-micro);
  line-height: var(--leading-micro);
}

.composer textarea {
  font-size: var(--type-body);
  line-height: 1.55;
}

.question-text,
.tool-card summary {
  font-size: var(--type-small);
  line-height: var(--leading-small);
}

.question-options button,
.question-own {
  font-size: var(--type-small);
  line-height: 1.3;
}

.toast-item,
.run-summary-head {
  font-size: var(--type-small);
  line-height: var(--leading-small);
}

.upload-item {
  font-size: var(--type-micro);
  line-height: var(--leading-micro);
}

.upload-item .upload-status,
.toast-item {
  overflow-wrap: anywhere;
}

.upload-item,
.upload-item .upload-status,
.run-time,
.file-size,
.msg .msg-meta,
.approval-status,
.run-summary-meta,
.run-summary-task,
.run-summary-task-label,
.plan-badge,
.pill,
.run-status,
.session-state {
  font-size: var(--type-micro);
  line-height: var(--leading-micro);
}

.run-status,
.pill,
.plan-badge {
  letter-spacing: var(--tracking-caps);
}

.plan-badge,
.pill,
.run-status,
.approval-label {
  font-weight: var(--weight-bold);
}

.session-state {
  font-weight: var(--weight-semibold);
}

.approval-status {
  font-weight: var(--weight-regular);
}

.plan-badge,
.pill,
.run-status,
.session-state,
.approval-status,
.pay-status,
.tariff-current,
.tariff-badge,
.copy-btn {
  line-height: 1.2;
}

.side-heading,
.user-menu-section {
  font-size: var(--type-micro);
  line-height: 1.3;
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
}

.ws-item,
.nav-link,
.file-row {
  font-size: var(--type-small);
  line-height: 1.35;
}

.ws-item .ws-name {
  font-size: var(--type-small);
  font-weight: var(--weight-semibold);
}

.ws-item .ws-meta {
  font-size: var(--type-micro);
  line-height: var(--leading-micro);
}

.run-row,
.user-chip,
.session-chip,
.crumb,
.crumb button,
.user-menu-item,
.ws-menu-item,
.user-menu-head .email {
  font-size: var(--type-meta);
  line-height: var(--leading-meta);
}

.user-menu-head .plan,
.topbar-status,
.settings-chip {
  font-size: var(--type-micro);
  line-height: var(--leading-micro);
}

.settings-chip {
  font-weight: var(--weight-semibold);
}

.kv {
  font-size: var(--type-small);
  line-height: var(--leading-small);
}

.kv dt {
  font-size: var(--type-meta);
}

.kv dd {
  overflow-wrap: anywhere;
}

.usage-label {
  font-size: var(--type-meta);
  line-height: var(--leading-meta);
}

.tariff-desc,
.tariff-features li,
.payment-box {
  font-size: var(--type-small);
  line-height: var(--leading-small);
}

.tariff-current,
.tariff-badge,
.pay-status,
.copy-btn {
  font-size: var(--type-micro);
  line-height: var(--leading-micro);
}

.tariff-current,
.tariff-badge,
.pay-status {
  letter-spacing: var(--tracking-caps);
}

/* --------------------------------------------------------------------------
   5. Code and keyboard text
   -------------------------------------------------------------------------- */
code,
kbd,
samp,
pre,
.editor,
.code-block,
.code-block code,
.msg code,
.approval-card code,
.changed-file,
.payment-code,
.fm-regex,
.fm-path-chip,
.fm-result-path,
.fm-result-preview,
.fm-status-path,
.fm-dest-path,
.fm-text-preview {
  font-family: var(--font-mono);
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0, "calt" 0;
}

code,
kbd,
samp {
  font-size: max(0.9em, 0.75rem);
  overflow-wrap: anywhere;
  hyphens: none;
  -webkit-hyphens: none;
}

pre {
  font-size: var(--type-code);
  line-height: var(--leading-code);
  tab-size: 4;
}

.msg pre,
.tool-card pre,
.approval-card pre,
.code-block,
.editor,
.fm-text-preview {
  font-size: var(--type-code);
  line-height: var(--leading-code);
}

.code-block code {
  font-size: 1em;
}

.editor,
.fm-text-preview {
  tab-size: 4;
}

.payment-code {
  font-size: 1rem;
  font-weight: var(--weight-semibold);
  letter-spacing: 0.04em;
}

/* --------------------------------------------------------------------------
   6. Tabular numerals for sizes, dates, counts and usage
   -------------------------------------------------------------------------- */
.run-time,
.file-size,
.fm-cell-size,
.fm-cell-date,
.fm-mobile-meta,
.fm-title-count,
.fm-statusbar,
.fm-results-summary,
.fm-result-line,
.fm-upload-status,
.fm-bulk-count,
.usage-label,
.tariff-price,
.payment-code,
.msg .msg-meta,
.approval-status,
.run-summary-meta,
.kv dd,
time {
  font-variant-numeric: var(--numeric-tabular);
}

/* --------------------------------------------------------------------------
   7. Long names, paths and Russian prose wrapping
   -------------------------------------------------------------------------- */
.msg,
.view-sub,
.auth-sub,
.form-note,
.fm-state p,
.fm-readonly-note span,
.tariff-desc,
.modal p {
  overflow-wrap: break-word;
  hyphens: auto;
  -webkit-hyphens: auto;
}

.fm-subtitle {
  overflow-wrap: anywhere;
}

.changed-file,
.panel-title code,
.tech-details code,
.fm-props-grid dd,
.fm-dest-hint,
.form-error,
.toast-item {
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   8. File-manager typography
   The file manager is the densest surface in the SPA. These overrides lift
   every meaningful label to the 12px floor without changing its layout.
   -------------------------------------------------------------------------- */
.fm-subtitle,
.fm-readonly-note,
.fm-state p,
.fm-preview-fallback p,
.fm-results-summary,
.fm-result-head,
.fm-dest-row,
.fm-dest-empty,
.fm-menu-item {
  font-size: var(--type-meta);
  line-height: var(--leading-meta);
}

.fm-btn,
.fm-mode-btn,
.fm-search-hint,
.fm-uploads-head,
.fm-upload,
.fm-upload-name small,
.fm-upload-status,
.fm-th,
.fm-sort-ind,
.fm-mobile-meta,
.fm-cell-size,
.fm-cell-date,
.fm-result-line,
.fm-statusbar,
.fm-status-path,
.fm-menu-label,
.fm-preview-path,
.fm-preview-loading,
.fm-props-kind,
.fm-props-grid dt,
.fm-dest-field label,
.fm-dest-hint,
.fm-dest-error,
.fm-path-chip,
.fm-result-preview,
.fm-bulk-count,
.fm-drop-overlay span {
  font-size: var(--type-micro);
  line-height: var(--leading-micro);
}

.fm-sort-mobile select {
  font-size: var(--type-meta);
  line-height: 1.35;
}

.fm-menu-sort > span {
  font-size: var(--type-micro);
  line-height: var(--leading-micro);
}

.fm-menu-sort select {
  font-size: var(--type-meta);
}

.fm-title-count {
  font-size: var(--type-micro);
  line-height: 1;
  font-variant-numeric: var(--numeric-tabular);
}

/* These two selectors exist in media queries in index.html with a higher
   specificity than .fm-btn; match them here so the 12px floor still wins. */
.fm-bulkbar .fm-btn,
.fm-header-actions .btn {
  font-size: var(--type-micro);
}

.fm-crumb {
  font-size: var(--type-meta);
}

.fm-crumb.current {
  font-weight: var(--weight-semibold);
}

.fm-crumb-sep {
  font-size: var(--type-micro);
}

.fm-search input,
.fm-dest-field input {
  font-size: var(--type-body);
  line-height: 1.4;
}

.fm-th {
  letter-spacing: 0.055em;
}

.fm-uploads-head {
  font-weight: var(--weight-semibold);
}

.fm-menu-label {
  letter-spacing: 0.06em;
}

.fm-name-text {
  font-size: var(--type-small);
  line-height: 1.35;
}

.fm-preview-title {
  font-size: var(--type-small);
  line-height: 1.35;
  font-weight: var(--weight-semibold);
}

.fm-props-grid dd {
  font-size: var(--type-meta);
  line-height: var(--leading-meta);
}

.fm-statusbar strong {
  font-weight: var(--weight-semibold);
}

.fm-text-preview {
  line-height: var(--leading-code);
}

/* --------------------------------------------------------------------------
   9. Mobile: 16px body and inputs, no iOS zoom on focus
   -------------------------------------------------------------------------- */
@media (max-width: 768px) {
  :root {
    --type-body: 1rem;        /* 16px body */
    --type-code: 0.875rem;    /* 14px code blocks */
  }

  body {
    line-height: 1.6;
  }

  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]),
  select,
  textarea,
  .session-picker-mobile select,
  .fm-sort-mobile select,
  .fm-menu-sort select,
  .fm-search input,
  .fm-dest-field input,
  .composer textarea,
  .editor {
    font-size: 1rem;
  }
}

/* --------------------------------------------------------------------------
   10. Temporary accessibility floor for legacy inline sizes
   index.html still contains a few inline font-size values below 12px. Inline
   styles cannot be beaten by a normal stylesheet rule, so these narrow
   attribute selectors use !important. Remove this block once those inline
   styles are normalised; nothing else in this file uses !important.
   -------------------------------------------------------------------------- */
[style*="font-size:9px"],
[style*="font-size:9.5px"],
[style*="font-size:10px"],
[style*="font-size:10.5px"],
[style*="font-size:11px"],
[style*="font-size:11.5px"] {
  font-size: var(--type-micro) !important;
}
