/* ==========================================================================
   Portal - Content page (app/Filament/Portal/Pages/Content.php)
   Layout/spacing only - no hardcoded colours. Every rule is scoped under
   .cxp-content-page (the wrapper only this page renders) so nothing here
   can reach Rankings, SearchPerformance, Dashboard or any other portal page.
   Loaded last in CyticxDesign::STYLES so it can out-specify cxp.css rules
   that were never designed for a 5-tile stat row or a 3-column data table.
   ========================================================================== */

/* ---- Fix 1/4: stat tile grid --------------------------------------------
   .cxp-rankings-stat-grid (cxp.css) is hardcoded to repeat(4, 1fr) for
   Rankings' 4 metric tiles. This page has 5 tiles and never applies that
   class - cxp-content-stat-grid is its own responsive column count so the
   5th tile ("Next article") never orphans onto a lone second row. ---- */
body.fi-panel-portal .cxp-content-stat-grid {
  display: grid;
  gap: 1rem;
  align-items: stretch;
  grid-template-columns: repeat(5, minmax(0, 1fr));
}
@media (max-width: 1399px) {
  body.fi-panel-portal .cxp-content-stat-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media (max-width: 900px) {
  body.fi-panel-portal .cxp-content-stat-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 480px) {
  body.fi-panel-portal .cxp-content-stat-grid {
    grid-template-columns: 1fr;
  }
}

/* Equal-height tiles even when one caption runs longer than its neighbours
   (e.g. "Next article" with nothing scheduled yet writes a full sentence). */
body.fi-panel-portal .cxp-content-page .cxp-rankings-stat {
  height: 100%;
}
body.fi-panel-portal .cxp-content-page .cxp-rankings-stat-caption {
  display: -webkit-box;
  /* 3, not 2: "Total blog articles we have written and published on your
     site." needs three lines and was cut mid-sentence on every client
     (scrollHeight 49 against clientHeight 32). Only 1 of the 5 content
     captions exceeds two lines, so the shared-baseline intent above is
     unchanged - the row just gains about 17px. */
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Fix 6: captions did not share a baseline - a tile with a one-line
     caption and a tile with a two-line caption left visibly uneven gaps
     below the value. .cxp-rankings-stat is display:flex/column (cxp.css),
     so margin-top:auto pushes every caption to the bottom of its tile,
     reading as one aligned band regardless of caption length above it. */
  margin-top: auto;
}

/* ---- Fix 1/2/3/5: table column discipline -------------------------------
   public/css/cxs-skin.css (the Duotone skin layer, loads after this file,
   do not edit it) forces AUTO layout on every .sb-data-table ON PURPOSE:

     body.fi-panel-portal .sb-data-table, .cxp-billing-plans, .cxp-billing-invoices
       gets table-layout: auto, marked !important.

   Its own "section 46" comment documents why: a width:1% plus nowrap idiom
   elsewhere on the panel is an AUTO-layout trick, "shrink this column to
   its content", and that idiom is the supported way to build a narrow
   metric column on this panel - fixed layout is not.

   We tried table-layout: fixed, marked !important, here first. It measured
   WORSE. cxs-skin.css also carries a rule that gives the first of several
   header cells width: 1% (a th:first-child selector guarded so it only
   fires when a later sibling th exists). Under auto layout that 1% is the
   same shrink-to-content idiom and is harmless. Under fixed layout the
   browser takes 1% literally, so the FIRST column - this page's prose
   column, on every table - collapsed to 1% of 1438px, 14px, with Published
   and Words absorbing the other 1,423px between them. Worse than the
   original bug. min-width cannot rescue it: fixed layout ignores min-width
   on cells (the same finding cxs-skin.css section 46 already documents).

   The real original cause of the 210px Article column was NOT auto layout
   itself - it was .cxp-content-truncate declaring max-width: 100% on a
   block inside a table cell. That is a cyclic width dependency (the cell's
   width depends on the block, the block's max-width depends on the cell),
   so under auto layout the browser treated the cell as contributing almost
   nothing to the column's intrinsic width and starved the prose column
   regardless of its real content.

   THE FIX: stay on the panel's supported auto-layout idiom. Metric, date
   and badge columns get width: 1%, white-space: nowrap, both !important -
   that forces them to their content's natural width and nothing more. The
   prose column gets width: auto, min-width: 0, both !important, so it
   absorbs whatever the metric columns do not need. .cxp-content-truncate
   drops max-width: 100% for max-width: none so it no longer starves the
   column it lives in. There is no colgroup in the Blade any more - it was
   meaningless under auto layout and only invited a future editor to try
   table-layout: fixed again, which is the one thing proven NOT to work on
   this panel.

   Measured after this fix (1920, table 1438px): Article 1231px, Published
   116px, Words 91px, rows 57px, zero horizontal overflow on the document or
   any .kt-table-wrap, at both 1920 and 1440. At 390px the table becomes
   display: block (the .cxp-mobile-card-table stacked pattern) and none of
   this applies. DO NOT reintroduce table-layout: fixed on this page - it
   collides with cxs-skin.css's th:first-child width:1% rule and produces a
   14px column with no obvious cause inside this file alone. ---- */
body.fi-panel-portal .cxp-content-page .cxp-content-table {
  table-layout: auto !important;
}
body.fi-panel-portal .cxp-content-page .cxp-content-table th,
body.fi-panel-portal .cxp-content-page .cxp-content-table td {
  box-sizing: border-box;
}

/* Prose-first tables (Published articles, Coming up, What we plan around):
   column 1 is prose, every column after it is a metric or a date - shrink
   those to their content with the panel's supported width:1% + nowrap
   idiom. */
body.fi-panel-portal .cxp-content-page .cxp-content-table--prose-first th:nth-child(n+2),
body.fi-panel-portal .cxp-content-page .cxp-content-table--prose-first td:nth-child(n+2) {
  width: 1% !important;
  white-space: nowrap !important;
}
body.fi-panel-portal .cxp-content-page .cxp-content-table--prose-first th:first-child,
body.fi-panel-portal .cxp-content-page .cxp-content-table--prose-first td:first-child {
  width: auto !important;
  min-width: 0 !important;
}

/* Site improvements: When (1%) / What we did (prose, column 2) / Type badge
   (1%) - the prose column is NOT column 1 here, so the prose-first rule
   above does not fit; this table gets its own selectors. */
body.fi-panel-portal .cxp-content-page .cxp-content-table--improvements th:nth-child(1),
body.fi-panel-portal .cxp-content-page .cxp-content-table--improvements td:nth-child(1),
body.fi-panel-portal .cxp-content-page .cxp-content-table--improvements th:nth-child(3),
body.fi-panel-portal .cxp-content-page .cxp-content-table--improvements td:nth-child(3) {
  width: 1% !important;
  white-space: nowrap !important;
}
body.fi-panel-portal .cxp-content-page .cxp-content-table--improvements th:nth-child(2),
body.fi-panel-portal .cxp-content-page .cxp-content-table--improvements td:nth-child(2) {
  width: auto !important;
  min-width: 0 !important;
}

/* Website text we improved: When (1%) / Page (capped 22%) / What changed
   (1%) / Before + After (prose, share whatever width is left). */
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text th:nth-child(1),
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text td:nth-child(1),
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text th:nth-child(3),
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text td:nth-child(3) {
  width: 1% !important;
  white-space: nowrap !important;
}
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text th:nth-child(2),
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text td:nth-child(2) {
  width: 22% !important;
}
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text th:nth-child(4),
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text td:nth-child(4),
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text th:nth-child(5),
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text td:nth-child(5) {
  width: auto !important;
  min-width: 0 !important;
}

/* One-line ellipsis for every prose cell (article titles, keyword sub-line,
   planned-article text, action titles, page label/path, topic names). The
   codebase already has a .cxp-cell-truncate idiom for this, but cxp.css only
   wires it under .cxp-dashboard-seo-details (Dashboard-only, off-limits) -
   this page needed its own class rather than depend on an ancestor it will
   never have. max-width is none, NOT 100 percent - see the table-layout
   comment above: max-width:100% on a block inside a table cell is a cyclic
   width dependency that starves the whole column under auto layout, which
   was the real original cause of the 210px Article column. */
body.fi-panel-portal .cxp-content-page .cxp-content-truncate {
  display: block;
  max-width: none;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
body.fi-panel-portal .cxp-content-page .cxp-content-truncate--sub {
  margin-top: .15rem;
}

/* Re-scope the existing cxp-cell-truncate idiom (Before/After cells on the
   "Website text we improved" tab) so it actually clips on this page - the
   metronic/cxp.css version only applies under .cxp-dashboard-seo-details,
   which this page never has. Same max-width:none reasoning as
   .cxp-content-truncate above: Before/After are this table's prose columns,
   so max-width:100% here would starve them the identical way. */
body.fi-panel-portal .cxp-content-page .cxp-cell-truncate {
  display: block;
  max-width: none;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- CYT-850: "What we changed" / "Type" amputated at 1440 -------------
   NOT a table-layout problem - the width:1% idiom above was already correct
   and untouched here. The real cause sits one layer OUT: .kt-card-table
   (the card wrapping every table on this page) is `display: grid`, and its
   child `.kt-card-content` is a grid item with the browser default
   `min-width: auto`, which means a grid item never shrinks below its
   content's min-content width. This table's content (several white-space:
   nowrap columns) had a min-content width of 1631px on the reproducing
   client at every desktop breakpoint, so `.kt-card-content` rendered at the
   full 1631px - wider than its own 1128px grid track at 1440 - while the
   OUTER `.kt-card` correctly stayed at 1128px with `overflow: hidden`. The
   result: the last ~500px of the row, including "What we changed" and
   "Type", was silently clipped by the card's own overflow, with no
   scrollbar (`.kt-table-wrap`'s overflow-x:auto never triggered because the
   wrap itself had already grown to match the oversized content - nothing
   to scroll). That is a full amputation, worse than the "reachable via the
   table's own horizontal scrollbar" lesser defect this ticket describes.

   `min-width: 0` restores the grid item's normal shrink-to-track behaviour.
   Scoped to this page only - `.kt-card-table` is a shared house pattern
   used by cards across the whole portal, and a global override would
   change how every OTHER wide-table card on the site is allowed to
   overflow its own card border. */
body.fi-panel-portal .cxp-content-page .kt-card-content {
  min-width: 0;
}

/* The second, larger cause of the same amputation: `.sb-dense-identity`
   (cxp.css, ported from the Style Book) is a `display: flex` NOWRAP row by
   design, built for a single-line "identity + short label" pattern used
   elsewhere in the portal. This page's "Page" column reuses it for a
   two-line pattern instead - page title on one line, path below
   (.cxp-content-truncate--sub already carries a margin-top for exactly
   that) - but the flex-row default laid title and path out SIDE BY SIDE
   with nowrap instead of stacked, so the column had to be as wide as BOTH
   strings combined (761-884px measured, against a ~230px longest single
   line). Reset to a plain block only on the page-text table's identity
   block - the OTHER .sb-dense-identity on this page (Published articles'
   title + read-time/section chips) is correctly a single-line row by
   design and must keep its flex layout, so this does not touch the shared
   cxp.css rule or the bare .sb-dense-identity selector. */
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text .sb-dense-identity {
  display: block;
  white-space: normal;
}

/* With the two structural causes above fixed, the table's real min-content
   width still exceeds the card at 1440/1120 on content-heavy accounts,
   because the prose spans upstream of "What we changed" / "Type" carry
   `max-width: none` (by design - see the comment above .cxp-content-truncate
   - a percentage cap there creates the documented circular-width bug under
   table-layout:auto). A hard PX ceiling avoids that circularity (it does
   not depend on the column's own resolved width) while still letting
   ellipsis do its job. clamp() keeps it proportional across breakpoints
   instead of a single fixed number that is too generous at 1440 and too
   tight at 1120, or the reverse. Order matters: these columns come BEFORE
   "What we changed" (page-text) or "Type" (improvements) in the row, so
   capping them is what keeps the badge column on-screen; "Detail" is the
   trailing/last column on the page-text table and gets the same treatment
   so the whole row fits without a scrollbar, but it is not the column this
   ticket is about. Measured zero overflow at 1920/1440/1120/390 on the
   reproducing client (yamifresh.com, "Search listing markup" in the Type
   column, longest real badge text in this dataset). */
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text td:nth-child(2) .cxp-content-truncate {
  max-width: clamp(84px, 13vw, 320px);
}
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text td:nth-child(4) .cxp-cell-truncate,
body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text td:nth-child(4) .cxp-content-truncate {
  max-width: clamp(110px, 15vw, 420px);
}
body.fi-panel-portal .cxp-content-page .cxp-content-table--improvements td:nth-child(2) .cxp-content-truncate {
  max-width: clamp(260px, 32vw, 620px);
}

/* Badges stay on one line inside their width:1% column, overriding the
   global "badges wrap" rule (CYT-605, cxp.css) that exists to protect
   auto-layout tables from a wide badge blowing out a column - on this page
   the badge's own column is already pinned to its content's width by the
   rules above, so a wrapped badge would only make the row taller for
   nothing. */
body.fi-panel-portal .cxp-content-page .cxp-content-table .kt-badge {
  white-space: nowrap;
}

/* ---- Mobile: .kt-table-wrap is display:none below 860px by house pattern
   (patterns.css around line 905) unless it also carries the house opt-out
   modifier kt-table-wrap--keep - without that modifier every table on this
   page vanished outright on any phone or small tablet: HTTP 200, all rows
   present in the DOM, table height literally 0. The Blade now adds
   kt-table-wrap--keep to every table wrapper on this page (all five tabs) -
   DO NOT remove it, that is what keeps the tables visible below 860px, not
   an accident or leftover markup.

   Below 640px .cxp-mobile-card-table switches the table to the stacked
   card pattern (display:block rows, data-label pseudo-headers). Without the
   reset below, this page's desktop column rules (width:1% !important,
   white-space:nowrap !important from the auto-layout fix above) kept
   applying inside that stacked layout, producing a 24px-wide "Published" /
   "Words" cell with the title still ellipsis-clipped. Reset them back to
   normal flow so text wraps naturally inside the card pattern instead. ---- */
@media (max-width: 640px) {
  body.fi-panel-portal .cxp-content-page .cxp-content-table th,
  body.fi-panel-portal .cxp-content-page .cxp-content-table td {
    width: auto !important;
    white-space: normal !important;
  }
  body.fi-panel-portal .cxp-content-page .cxp-content-truncate,
  body.fi-panel-portal .cxp-content-page .cxp-cell-truncate {
    white-space: normal !important;
    overflow: visible !important;
  }

  /* CYT-851: the generic th/td reset just above cannot beat the desktop
     .cxp-content-table--page-text td:nth-child(2) { width: 22% !important }
     rule higher up this file - that nth-child selector is more specific, so
     "22% of the card row" (about 68-80px on a 390px phone) survived into the
     stacked card layout. The Page grid column (minmax(0, 1fr) from cxp.css)
     inherited that squeeze, so a normal value like "Homepage" had nowhere to
     wrap except mid-word via overflow-wrap, rendering as a vertical
     single-letter stack. Match the desktop selector's specificity so this
     wins, letting the column take its natural grid width instead. */
  body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text th:nth-child(2),
  body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text td:nth-child(2) {
    width: auto !important;
  }

  /* CYT-852: same root cause as CYT-851 above, on the columns CYT-851 did not
     touch. .cxp-content-table--page-text td:nth-child(1)/(3) and .cxp-content-
     table--improvements td:nth-child(1)/(3) carry the desktop auto-layout idiom
     width:1% !important; white-space:nowrap !important (the auto-layout fix
     block above) at the same nth-child specificity that beat the generic reset
     for the Page column. For nth-child(3) (a badge cell: What we changed /
     Type) the squeezed ~24px-wide grid container still lays out its two columns
     at their track-minimum sizes (label col: minmax(6.75rem,38%) keeps its
     108px floor; value col: minmax(0,1fr) is left with 0), so the badge renders
     at that 0-width column's start position directly over the tail of the label
     text instead of below it - the label and badge text run together. nth-
     child(1) (When) carries the identical rule but currently reads fine only
     because a short date happens not to overflow visibly; it gets the same
     reset here so it does not regress the same way the next time a longer date
     format or locale is used. */
  body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text th:nth-child(1),
  body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text td:nth-child(1),
  body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text th:nth-child(3),
  body.fi-panel-portal .cxp-content-page .cxp-content-table--page-text td:nth-child(3),
  body.fi-panel-portal .cxp-content-page .cxp-content-table--improvements th:nth-child(1),
  body.fi-panel-portal .cxp-content-page .cxp-content-table--improvements td:nth-child(1),
  body.fi-panel-portal .cxp-content-page .cxp-content-table--improvements th:nth-child(3),
  body.fi-panel-portal .cxp-content-page .cxp-content-table--improvements td:nth-child(3) {
    width: auto !important;
    white-space: normal !important;
  }
}

/* ---- Fix 3: row density --------------------------------------------------
   .kt-table tbody td padding-block is .75rem top+bottom (24px) by default.
   A 2-line article cell (title + keyword) at that padding lands near 62px;
   trimmed here so the whole table sits in the ~52-60px band the owner
   measured against. Single-line rows (Coming up, Site improvements, What we
   plan around) come down proportionally. */
body.fi-panel-portal .cxp-content-page .cxp-content-table tbody td {
  padding-block: .55rem;
}

/* ---- Round-2 fix: tab bar was a half-empty bordered box -----------------
   REMOVED for CYT-802. This page once carried its own copy of "make the tab
   strip hug its buttons": .cxp-map-tabs is a grid item inside .cxp-map-details,
   so it stretched to the full column - 1440px wide around five buttons that
   spanned 730px - until `justify-self: start` opted it out of the grid's
   default stretch and `width: fit-content` sized it to its labels. That worked,
   and it was the right diagnosis; it was just scoped to one page.

   It is now the product-wide default. pages.css declares the same
   `width: fit-content !important; justify-self: start !important` on the
   canonical .cxp-map-tabs component for every portal page, so this file no
   longer needs an opinion about it - measured live at 1440 with this block
   deleted, the strip is 716.7px, hugging its five labels, zero overflow, and
   390px still stacks. A per-page copy of a component fix IS the defect CYT-802
   was filed about, so the copy goes with the fix. */

/* ---- Round-2 fix: "At a glance" read like a link, not a section heading -
   Rankings.php gets its own scoped heading treatment (patterns.css,
   .cxp-rankings-page .kt-card-title - red accent + icon, explicitly NOT
   approved for portal-wide rollout per that file's own CYT-618 comment) and
   a separate, unbranded size bump (components.css,
   .cxp-rankings-page .cxp-rankings-kpi-heading .kt-card-title -
   font-size:1.05rem). This page has neither, since it never carries the
   cxp-rankings-page class, so "At a glance" fell back to the bare
   .kt-card-title base rule (1rem, semibold) with no card-header context to
   give it visual weight - which reads as body text/a link, not a heading.
   This mirrors ONLY the unbranded size convention already established for
   this exact "kpi-heading" pattern elsewhere in the codebase, without
   adopting the Rankings-specific colour/icon branding that is gated. */
body.fi-panel-portal .cxp-content-page .cxp-rankings-kpi-heading .kt-card-title {
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.3;
  margin: 0;
}

/* ---- Round-2 fix: tighten the gap between the tab bar and the table it
   controls. .cxp-map-details (cxp.css) is display:grid; gap:1rem - the same
   16px every other portal page's tab pattern uses, which reads fine there
   because their tab bar visually fills the row. Now that the tab bar above
   hugs its own buttons instead of stretching, the same 16px reads as a much
   bigger gap relative to the button row's height, so it is tightened here
   specifically for this page. */
body.fi-panel-portal .cxp-content-page .cxp-map-details {
  gap: .5rem;
}

/* ---- CYT-884: Published articles - search/sort toolbar and pager, sticky
   header on scroll. Same shape as the Reviews page pager
   (filament-bridge.css, .cxp-rv-pager) and WebsiteHealth's Crawled-pages
   controls (cxp-wh3-table-controls / cxp-wh3-pagination) - reused rather
   than invented so the portal keeps one paginated-table language. ---- */
body.fi-panel-portal .cxp-content-page .cxp-tbl-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  flex-wrap: wrap;
  padding: 0 1rem .75rem;
}
body.fi-panel-portal .cxp-content-page .cxp-tbl-search {
  max-width: 16rem;
  flex: 1 1 12rem;
}
body.fi-panel-portal .cxp-content-page .cxp-tbl-sort {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: 12px;
  color: var(--muted-foreground);
}
body.fi-panel-portal .cxp-content-page .cxp-tbl-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: .6rem 1rem;
  border-top: 1px solid var(--border);
}
body.fi-panel-portal .cxp-content-page .cxp-tbl-pager__pages {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
}
body.fi-panel-portal .cxp-content-page .cxp-tbl-pager__btn {
  min-width: 2.1rem;
  justify-content: center;
}
body.fi-panel-portal .cxp-content-page .cxp-tbl-pager__btn.is-active {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--primary-foreground, #fff);
}
/* CYT-884 QA fix: .4 read as "very low-contrast" against the card
   background - raised so a disabled prev/next arrow is still legible, not
   just barely-there. */
body.fi-panel-portal .cxp-content-page .cxp-tbl-pager__btn.is-disabled {
  opacity: .65;
  color: var(--muted-foreground);
  pointer-events: none;
}
body.fi-panel-portal .cxp-content-page .cxp-tbl-pager__ellipsis {
  padding: 0 .3rem;
  color: var(--muted-foreground);
  user-select: none;
}
@media (max-width: 640px) {
  body.fi-panel-portal .cxp-content-page .cxp-tbl-toolbar { padding: 0 .75rem .6rem; }
  body.fi-panel-portal .cxp-content-page .cxp-tbl-search { max-width: none; flex-basis: 100%; }
  body.fi-panel-portal .cxp-content-page .cxp-tbl-pager { justify-content: center; }
  body.fi-panel-portal .cxp-content-page .cxp-tbl-pager__pages { width: 100%; justify-content: center; flex-wrap: wrap; }
}

/* Sticky header on scroll: caps the table body so a large page (up to 50
   rows) keeps its column labels in view instead of scrolling them away -
   same sticky-thead idiom cyticx-theme.css's .st-table already uses
   elsewhere. Only engages once content exceeds the cap; the common 10-row
   page fits inside it and never shows a scrollbar. Reset below 640px: the
   house .cxp-mobile-card-table pattern visually hides <thead> there
   (cxp.css) and switches to stacked cards, so a vertical scroller has
   nothing left to stick and would only clip the stacked rows oddly. */
body.fi-panel-portal .cxp-content-page .kt-table-wrap--scroll-y {
  max-height: 640px;
  overflow-y: auto;
}
body.fi-panel-portal .cxp-content-page .kt-table-wrap--scroll-y thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--card);
}
@media (max-width: 640px) {
  body.fi-panel-portal .cxp-content-page .kt-table-wrap--scroll-y {
    max-height: none;
    overflow-y: visible;
  }
}

/* CYT-884 QA fix: keep "in /" together as one unbreakable unit in the
   Links cell so a narrow mobile card can only wrap before "0 out", never
   stranding the "/" alone on its own line between "4 in" and "0 out". */
body.fi-panel-portal .cxp-content-page .cxp-article-links-nowrap {
  white-space: nowrap;
}

/* CYT-884 QA fix: on the stacked mobile card (.cxp-mobile-card-table td is
   a 2-column CSS grid - see cxp.css), a grid item stretches to fill its
   column by the browser's own default (justify-items: stretch) unless told
   otherwise. Every sibling value is plain text, which never visibly needs
   the full column width; the Details <button> does, so it alone rendered
   noticeably wider/"oversized" against its row neighbours. Sizing it to its
   own content restores it to the same visual weight as the other rows. */
@media (max-width: 640px) {
  body.fi-panel-portal .cxp-content-page .cxp-article-toggle-cell .cxp-article-toggle {
    justify-self: start;
    width: fit-content;
  }
}
