/* =====================================================================
   A project's own page — the tab shell, and the Overview tab
   ---------------------------------------------------------------------
   Two things live here.

   1. `.nz-ptabs26` — the tab strip and the pane it selects, as ONE card.
      The strip used to float on the page and each tab then drew a card
      of its own underneath it, so the reader saw two boxes for one
      thing; and the Overview, which is a grid of widgets rather than a
      single card, had no box at all. See the section at the end.

   2. `.nz-project26` — the Overview tab itself.
   ---------------------------------------------------------------------
   The overview tab wears `.nz-dash26 .nz-project26`, so
   assets/css/dashboard-ios26.css already gives it the glass cards, the
   section headings, the stat tiles, the chart boxes, the badge/ins/del
   contrast repairs and the phone behaviour. Everything below is what a
   PROJECT needs on top of that and nothing else:

     - the progress ring and its readout
     - the "are we on schedule" comparison (two bars, one question)
     - the grouped meta list (start date, client, status, ...)
     - a doughnut legend that carries the counts, so the chart itself
       needs no labels
     - the horizontal category bars (priorities)
     - the people rows (workload) and the milestone rows
     - the description body

   Every colour here is an --ios26-* token or a hue stated TWICE, once
   per theme. Nothing reads its colour from a Bootstrap default: those
   are chosen for a white page and the dark theme overrides only a fixed
   list of classes.
   ===================================================================== */

/* ========================================================= the ring ===
   Pure SVG rather than a Chart.js doughnut: a ring that has to carry a
   number in the middle is three lines of markup this way, and it keeps
   its stroke colours as CSS (so dark mode is a token swap) instead of
   as a data array baked into a script.
   ===================================================================== */

.nz-project26 .nz-po-ring {
    position: relative;
    width: 170px;
    height: 170px;
    margin: 4px auto 2px;
}

.nz-project26 .nz-po-ring svg {
    display: block;
    width: 100%;
    height: 100%;

    /* the arc starts at 12 o'clock. This is a CSS transform, and the
       <circle> carries no transform ATTRIBUTE, so there is nothing for
       it to silently override */
    transform: rotate(-90deg);
}

.nz-project26 .nz-po-ring-track {
    fill: none;
    stroke: var(--ios26-fill);
    stroke-width: 12;
}

.nz-project26 .nz-po-ring-value {
    fill: none;
    stroke: var(--nz-tint, var(--ios26-accent));
    stroke-width: 12;
    stroke-linecap: round;
    transition: stroke-dashoffset 0.9s var(--ios26-ease);
}

.nz-project26 .nz-po-ring-text {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    text-align: center;
}

.nz-project26 .nz-po-ring-figure {
    font-size: 38px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    color: var(--ios26-text);
}

.nz-project26 .nz-po-ring-label {
    font-size: 12px;
    line-height: 1.3;
    color: var(--ios26-muted);
}

/* ====================================================== meta list =====
   The iOS grouped list: a label on the left in the muted tone, its
   value on the right in the text tone, a hairline between rows. Used for
   the project's own facts and for the custom fields, so the two read as
   one list rather than as two different ideas about what a field is.
   ===================================================================== */

.nz-project26 .nz-po-meta {
    display: flex;
    flex-direction: column;
}

.nz-project26 .nz-po-meta-row {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 10px 0;
    font-size: 13.5px;
    line-height: 1.45;
}

.nz-project26 .nz-po-meta-row + .nz-po-meta-row {
    border-top: 1px solid var(--ios26-hairline);
}

.nz-project26 .nz-po-meta-label {
    flex: 0 0 auto;
    min-width: 108px;
    color: var(--ios26-muted);
}

.nz-project26 .nz-po-meta-value {
    flex: 1 1 auto;
    min-width: 0;
    text-align: right;
    color: var(--ios26-text);
    font-weight: 500;
    overflow-wrap: anywhere;
}

/* a link inside a value keeps the accent, not the app's default blue */
.nz-project26 .nz-po-meta-value a {
    color: var(--ios26-accent-strong);
}

body.color-1E202D .nz-project26 .nz-po-meta-value a {
    color: #93a9f7;
}

/* a custom field's value can be a paragraph, a list or an image — it
   must not be forced onto one right-aligned line */
.nz-project26 .nz-po-meta-row.is-block {
    display: block;
}

.nz-project26 .nz-po-meta-row.is-block .nz-po-meta-value {
    text-align: left;
    margin-top: 3px;
}

/* ================================================== schedule bars =====
   "Are we on track" is one question with two numbers: how much of the
   time is gone, and how much of the work is done. Two bars on the same
   scale answer it in one glance — the second bar shorter than the first
   IS being behind, and nobody has to subtract anything.
   ===================================================================== */

.nz-project26 .nz-po-track-group {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.nz-project26 .nz-po-track-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 6px;
    font-size: 13px;
    color: var(--ios26-muted);
}

.nz-project26 .nz-po-track-value {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    color: var(--ios26-text);
}

.nz-project26 .nz-po-track {
    position: relative;
    height: 10px;
    border-radius: var(--ios26-pill);
    background: var(--ios26-fill);
    overflow: hidden;
}

.nz-project26 .nz-po-track-fill {
    height: 100%;
    border-radius: var(--ios26-pill);
    background: var(--ios26-accent);
    transition: width 0.9s var(--ios26-ease);
}

.nz-project26 .nz-po-track-fill.is-time {
    background: #8e7cf0;
}

.nz-project26 .nz-po-track-fill.is-work {
    background: #01b393;
}

.nz-project26 .nz-po-track-fill.is-behind {
    background: #f5325c;
}

body.color-1E202D .nz-project26 .nz-po-track-fill.is-time {
    background: #a898f5;
}

body.color-1E202D .nz-project26 .nz-po-track-fill.is-work {
    background: #3fd3b4;
}

body.color-1E202D .nz-project26 .nz-po-track-fill.is-behind {
    background: #ff6b8a;
}

/* the verdict under the two bars, in words — the bars show it, this
   says it, and one of the two always reaches the reader */
.nz-project26 .nz-po-verdict {
    margin: 2px 0 0;
    font-size: 13px;
    line-height: 1.45;
    color: var(--ios26-muted);
}

/* ==================================================== status chips ====
   A chip is a soft tint of a hue behind text of the SAME hue at readable
   strength — never the Bootstrap contextual badge, which paints the
   app's default grey on a saturated fill (measured 1.12:1 on bg-success).
   ===================================================================== */

.nz-project26 .nz-po-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.nz-project26 .nz-po-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;

    padding: 5px 11px;
    border: 1px solid var(--ios26-hairline);
    border-radius: var(--ios26-pill);

    background: var(--ios26-fill);
    color: var(--ios26-text);

    font-size: 12px;
    font-weight: 500;
    line-height: 1.3;
    white-space: nowrap;
}

.nz-project26 .nz-po-chip i {
    font-size: 11px;
    opacity: 0.75;
}

.nz-project26 .nz-po-chip.is-danger {
    border-color: rgba(245, 50, 92, .24);
    background: rgba(245, 50, 92, .12);
    color: #a8103a;
}

.nz-project26 .nz-po-chip.is-warning {
    border-color: rgba(214, 145, 0, .28);
    background: rgba(250, 193, 8, .18);
    color: #7a5200;
}

.nz-project26 .nz-po-chip.is-success {
    border-color: rgba(1, 179, 147, .26);
    background: rgba(1, 179, 147, .14);
    color: #0b6b59;
}

body.color-1E202D .nz-project26 .nz-po-chip.is-danger {
    border-color: rgba(255, 107, 138, .28);
    background: rgba(245, 50, 92, .20);
    color: #ff9db1;
}

body.color-1E202D .nz-project26 .nz-po-chip.is-warning {
    border-color: rgba(250, 193, 8, .26);
    background: rgba(250, 193, 8, .18);
    color: #f5cf65;
}

body.color-1E202D .nz-project26 .nz-po-chip.is-success {
    border-color: rgba(87, 220, 192, .26);
    background: rgba(1, 179, 147, .20);
    color: #57dcc0;
}

/* ================================================ doughnut legend =====
   The chart draws the shape; this carries the numbers. Chart.js' own
   legend is a row of wrapping pills with no counts in them, which is
   exactly the part the reader wanted.
   ===================================================================== */

.nz-project26 .nz-po-legend {
    list-style: none;
    margin: 14px 0 0;
    padding: 0;
}

.nz-project26 .nz-po-legend li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    font-size: 13px;
}

.nz-project26 .nz-po-legend li + li {
    border-top: 1px solid var(--ios26-hairline);
}

.nz-project26 .nz-po-dot {
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    border-radius: 50%;

    /* a status colour can be near-white; the inner hairline keeps the
       dot visible on the light card as well as on the dark one */
    box-shadow: inset 0 0 0 1px rgba(17, 24, 39, .18);
}

body.color-1E202D .nz-project26 .nz-po-dot {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
}

.nz-project26 .nz-po-legend-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--ios26-text);
}

.nz-project26 .nz-po-legend-share {
    flex: 0 0 auto;
    min-width: 42px;
    text-align: right;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    color: var(--ios26-muted);
}

.nz-project26 .nz-po-legend-value {
    flex: 0 0 auto;
    min-width: 34px;
    text-align: right;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    color: var(--ios26-text);
}

/* ================================================= category bars ======
   Priorities, and anything else that is "a name, a count, and how big
   that count is next to the others". A bar chart with two categories is
   chart junk; this is the same information in a grouped list.
   ===================================================================== */

.nz-project26 .nz-po-bars {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.nz-project26 .nz-po-bar-head {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 7px;
    font-size: 13px;
}

.nz-project26 .nz-po-bar-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--ios26-text);
}

.nz-project26 .nz-po-bar-value {
    flex: 0 0 auto;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    color: var(--ios26-text);
}

.nz-project26 .nz-po-bar-track {
    height: 8px;
    border-radius: var(--ios26-pill);
    background: var(--ios26-fill);
    overflow: hidden;
}

/* the priority's own hue, the same one the task lists use. A status or
   priority colour is picked by the workspace and can be near-white
   (#aab7b7 ships as "Minor"), so the icon keeps a fixed width and the
   COUNT beside it carries the meaning in text either way. */
.nz-project26 .nz-po-bar-icon {
    flex: 0 0 auto;
    width: 16px;
    text-align: center;
    font-size: 13px;
}

.nz-project26 .nz-po-bar-fill {
    height: 100%;
    border-radius: var(--ios26-pill);
    transition: width 0.9s var(--ios26-ease);

    /* a pale fill on a pale track is an empty bar; the hairline keeps
       its edge readable in both themes */
    box-shadow: inset 0 0 0 1px rgba(17, 24, 39, .14);
}

body.color-1E202D .nz-project26 .nz-po-bar-fill {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
}

/* ====================================================== people ========
   One row per member: who, what they carry, what they have finished,
   and the hours they put in. The figures are a fixed grid so the
   columns line up down the list and can be compared vertically.
   ===================================================================== */

.nz-project26 .nz-po-people {
    display: flex;
    flex-direction: column;
}

.nz-project26 .nz-po-person {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 0;
}

.nz-project26 .nz-po-person + .nz-po-person {
    border-top: 1px solid var(--ios26-hairline);
}

.nz-project26 .nz-po-avatar {
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid var(--ios26-edge);
    background: var(--ios26-fill);
}

.nz-project26 .nz-po-person-main {
    flex: 1 1 auto;
    min-width: 0;
}

.nz-project26 .nz-po-person-name {
    display: block;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: -0.006em;
    color: var(--ios26-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nz-project26 a .nz-po-person-name:hover {
    color: var(--ios26-accent-strong);
}

body.color-1E202D .nz-project26 a .nz-po-person-name:hover {
    color: #93a9f7;
}

.nz-project26 .nz-po-person-sub {
    display: block;
    margin-top: 1px;
    font-size: 12px;
    line-height: 1.35;
    color: var(--ios26-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nz-project26 .nz-po-figures {
    display: flex;
    flex: 0 0 auto;
    gap: 6px;
}

.nz-project26 .nz-po-figure {
    min-width: 52px;
    text-align: center;
}

.nz-project26 .nz-po-figure-value {
    display: block;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    color: var(--ios26-text);
}

.nz-project26 .nz-po-figure-value.is-zero {
    color: var(--ios26-muted);
    font-weight: 500;
}

.nz-project26 .nz-po-figure-value.is-late {
    color: #a8103a;
}

body.color-1E202D .nz-project26 .nz-po-figure-value.is-late {
    color: #ff9db1;
}

.nz-project26 .nz-po-figure-label {
    display: block;
    margin-top: 2px;
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.055em;
    text-transform: uppercase;
    color: var(--ios26-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* a phone has no room for three figure columns beside a name */
@media (max-width: 480px) {
    .nz-project26 .nz-po-person {
        flex-wrap: wrap;
    }

    .nz-project26 .nz-po-figures {
        width: 100%;
        justify-content: space-between;
        padding-left: 48px;
    }
}

/* =================================================== milestones =======
   Each one is a date, a title and how much of its work is finished. The
   date leads, because a milestone is a promise about a day.
   ===================================================================== */

.nz-project26 .nz-po-milestone {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 12px 0;
}

.nz-project26 .nz-po-milestone + .nz-po-milestone {
    border-top: 1px solid var(--ios26-hairline);
}

.nz-project26 .nz-po-date {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    width: 46px;
    padding: 6px 0;

    border: 1px solid var(--ios26-edge);
    border-radius: 12px;
    background: var(--ios26-fill);
    box-shadow: var(--ios26-inset);
}

.nz-project26 .nz-po-date-day {
    font-size: 17px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--ios26-text);
}

.nz-project26 .nz-po-date-month {
    margin-top: 2px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ios26-muted);
}

.nz-project26 .nz-po-milestone.is-late .nz-po-date {
    border-color: rgba(245, 50, 92, .3);
    background: rgba(245, 50, 92, .12);
}

.nz-project26 .nz-po-milestone.is-late .nz-po-date-day,
.nz-project26 .nz-po-milestone.is-late .nz-po-date-month {
    color: #a8103a;
}

body.color-1E202D .nz-project26 .nz-po-milestone.is-late .nz-po-date-day,
body.color-1E202D .nz-project26 .nz-po-milestone.is-late .nz-po-date-month {
    color: #ff9db1;
}

.nz-project26 .nz-po-milestone-main {
    flex: 1 1 auto;
    min-width: 0;
}

.nz-project26 .nz-po-milestone-title {
    display: block;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--ios26-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nz-project26 .nz-po-milestone-sub {
    display: block;
    margin: 2px 0 7px;
    font-size: 12px;
    color: var(--ios26-muted);
}

/* ==================================================== description =====
   The project brief, which is now the card that used to be the activity
   log. It is prose written by a person, so it gets a reading measure and
   the app's own rich-text children get sane defaults — an <img> pasted
   into a description is routinely 2000px wide.
   ===================================================================== */

.nz-project26 .nz-po-desc {
    max-width: 78ch;
    font-size: 14.5px;
    line-height: 1.62;
    color: var(--ios26-text);
    overflow-wrap: anywhere;
}

.nz-project26 .nz-po-desc > *:first-child {
    margin-top: 0;
}

.nz-project26 .nz-po-desc > *:last-child {
    margin-bottom: 0;
}

.nz-project26 .nz-po-desc img {
    max-width: 100%;
    height: auto;
    border-radius: var(--ios26-radius);
}

.nz-project26 .nz-po-desc a {
    color: var(--ios26-accent-strong);
}

body.color-1E202D .nz-project26 .nz-po-desc a {
    color: #93a9f7;
}

.nz-project26 .nz-po-desc h1,
.nz-project26 .nz-po-desc h2,
.nz-project26 .nz-po-desc h3,
.nz-project26 .nz-po-desc h4 {
    color: var(--ios26-text);
    letter-spacing: -0.012em;
}

.nz-project26 .nz-po-desc blockquote {
    margin: 14px 0;
    padding: 2px 0 2px 16px;
    border-left: 3px solid var(--ios26-hairline-strong);
    color: var(--ios26-muted);
}

.nz-project26 .nz-po-desc code,
.nz-project26 .nz-po-desc pre {
    background: var(--ios26-fill);
    color: var(--ios26-text);
    border-radius: var(--ios26-radius-sm);
}

.nz-project26 .nz-po-desc pre {
    padding: 12px 14px;
    overflow-x: auto;
}

/* =================================================== activity log =====
   Last band on the page, and the one that can be arbitrarily long: it
   scrolls inside its own card instead of pushing the page to ten
   screens. The rows themselves are the app's activity widget, already
   repaired for the glass by dashboard-ios26.css.
   ===================================================================== */

.nz-project26 .nz-po-activity {
    max-height: 560px;
    overflow-y: auto;
}

.nz-project26 .nz-po-activity .border-bottom {
    border-bottom-color: var(--ios26-hairline) !important;
}

/* the widget's own "load more" link */
.nz-project26 .nz-po-activity .text-center a {
    color: var(--ios26-accent-strong);
}

body.color-1E202D .nz-project26 .nz-po-activity .text-center a {
    color: #93a9f7;
}

/* ================================================== small screens =====
   Below 800px the whole page is one column of cards (Bootstrap does the
   stacking); the only thing that needs saying is that a 170px ring in a
   360px card is out of proportion.
   ===================================================================== */

@media (max-width: 575px) {
    .nz-project26 .nz-po-ring {
        width: 142px;
        height: 142px;
    }

    .nz-project26 .nz-po-ring-figure {
        font-size: 32px;
    }

    .nz-project26 .nz-po-meta-label {
        min-width: 88px;
    }
}

/* ====================================================== KPI readout ====
   The strip at the top of the tab: six of these across a wide screen.
   The dashboard's own .nz-stat-card puts the plate, the label and the
   figure on ONE line, which needs about 280px — at 190px every label in
   this strip was ellipsised ("Team me…", "Due this …"). Here the figure
   sits opposite the plate and the label owns the width underneath, so
   the same card reads at a third of the width.
   ===================================================================== */

.nz-project26 .nz-po-kpi > .card-body {
    gap: 10px;
}

.nz-project26 .nz-po-kpi .nz-po-kpi-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

/* the label may take two lines here — it is on its own row, so a second
   line costs the card height it has, not the figure's space. Three
   would make the tiles in a band different heights again. */
.nz-project26 .nz-po-kpi .nz-stat-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    white-space: normal;
    overflow: hidden;
}

.nz-project26 .nz-po-kpi .nz-stat-sub {
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* a currency figure ("€20,959.92") is three times as wide as a task
   count; fitFigures() in dashboard-ios26.js steps it down, and this is
   the floor it steps within */
.nz-project26 .nz-po-kpi .nz-stat-figure {
    font-size: 24px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ============================================== tiles that navigate ===
   A KPI readout that names a project tab opens it. It is not an anchor
   — the tabs are ajax panes driven by a click on their own <a> — so the
   affordance has to be stated here, and the focus ring has to be too.
   ===================================================================== */

.nz-project26 .nz-po-tile-link {
    cursor: pointer;
}

.nz-project26 .nz-po-tile-link:hover {
    transform: translateY(-2px);
    box-shadow: var(--ios26-inset), var(--ios26-shadow-2) !important;
}

.nz-project26 .nz-po-tile-link:focus-visible {
    outline: 2px solid var(--ios26-accent);
    outline-offset: 2px;
}

/* ================================================ filling the card ====
   Every card in a band is stretched to the height of its tallest
   neighbour (that is what makes their figures comparable), but the
   dashboard's card body is `flex: 0 1 auto` — it never grows. So a
   short widget beside a tall one ended with a strip of dead space under
   it, and an EMPTY state ("No milestones yet") floated at the top of a
   400px card.

   Letting the body grow is safe here, and only here, because every plot
   on this tab lives in a `.nz-chart-box` with a height of its own — the
   growth loop the dashboard sheet warns about needs a canvas with
   `maintainAspectRatio: false` and NO container height, which this tab
   does not have. The box is pinned against shrinking for the same
   reason.
   ===================================================================== */

.nz-project26 .card > .card-body {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
}

.nz-project26 .card > .card-body > .nz-chart-box {
    flex: 0 0 auto;
}

/* ...except a plot that is the card's whole point. It takes the space
   its neighbours forced the card to have, instead of leaving it blank
   underneath. It still cannot DRIVE the height: the body is sized by
   the row, so there is no canvas -> container -> card loop. */
.nz-project26 .card > .card-body > .nz-chart-box.nz-po-chart-grow {
    flex: 1 1 auto;
}

/* an empty state is the card's whole message; it should sit in the
   middle of it, not cling to the top */
.nz-project26 .card .nz-chart-empty {
    flex: 1 1 auto;
    justify-content: center;
}

/* three priority rows in a card stretched to a doughnut's height read
   better centred than stacked against the title */
.nz-project26 .nz-po-bars {
    flex: 1 1 auto;
    justify-content: center;
}

/* two KPI readouts across a phone: the plate and the figure share a
   line that is now 175px wide, so both give up a little */
@media (max-width: 575px) {
    .nz-project26 .nz-po-kpi > .card-body {
        padding: 13px 14px !important;
        gap: 8px;
    }

    .nz-project26 .nz-po-kpi .widget-icon {
        width: 32px;
        height: 32px;
        border-radius: 10px;
    }

    .nz-project26 .nz-po-kpi .widget-icon i {
        font-size: 14px;
    }

    .nz-project26 .nz-po-kpi .nz-stat-figure {
        font-size: 21px;
    }

    .nz-project26 .nz-po-kpi .nz-stat-title {
        font-size: 13px;
    }

    .nz-project26 .nz-po-kpi .nz-stat-sub {
        font-size: 11px;
    }
}

/* =================================================== the tab shell ====
   The strip and its pane are one card.

   Before this the strip floated on the page with `mb20` under it, and
   every tab then opened a card of its own — two boxes for one thing.
   The Overview had the opposite problem: it is a GRID of widgets, not a
   single card, so it had no box at all and its bands ran loose down the
   page while every other tab sat in one.

   So: the shell draws the box, once. A pane that is a single card is
   flattened onto it (below). A pane that is a grid of widgets — the
   Overview — keeps its widgets and the shell is the surface they sit
   on, which is why the shell uses the SOFT surface token and the
   widgets the strong one: two steps apart, so glass on glass still
   reads as glass.
   ===================================================================== */

.nz-ptabs26 {
    position: relative;
    margin: 6px 0 24px;

    border: 1px solid var(--ios26-edge);
    border-radius: var(--ios26-radius-lg);
    background: var(--ios26-surface-soft);
    box-shadow: var(--ios26-inset), var(--ios26-shadow-1);

    /* NOT `overflow: hidden`, tempting as it is for the strip's corners:
       every appTable in every pane hangs its export menu, its column
       menu and its row actions out of the card, and clipping them makes
       those menus unusable. The strip rounds its own top corners
       instead. */
    overflow: visible;
}

/* The strip may or may not be a direct child of the shell:
   assets/js/tabs-scroller.js wraps a bar that OVERFLOWS in
   `div.nz-tabscroll` and turns the <ul> into the scrollport
   (`.nz-tabscroll-track`). A project has eleven to sixteen tabs, so on
   most screens it is wrapped — and a rule written only for the direct
   child silently stops applying at the width where it matters most.
   Both shapes, every time. */
.nz-ptabs26 > .nav-tabs,
.nz-ptabs26 > .nz-tabscroll {
    margin: 0 !important;
    border-bottom: 1px solid var(--ios26-hairline);
    border-radius: var(--ios26-radius-lg) var(--ios26-radius-lg) 0 0;
    background: transparent;
}

/* The selection capsule (assets/js/ios26-tabs.js) casts
   `0 4px 14px rgba(17,24,39,.12)`: it needs ~10px of room above it and
   ~18px below. It had 6, and when the strip is wrapped the scrollport's
   own `overflow-y: hidden` cut the shadow off flat at top and bottom.

   Padding is the fix in both shapes, because a scrollport clips at its
   PADDING edge, not at the content edge. `padding-block` only — the
   40px inline padding belongs to tabs-scroller.js, which reserves it for
   the two arrow buttons and sets it `!important`. */
.nz-ptabs26 > .nav-tabs,
.nz-ptabs26 > .nz-tabscroll > .nav-tabs {
    padding-block: 12px 14px;
}

.nz-ptabs26 > .nav-tabs {
    padding-inline: 12px;
}

/* and the pane starts below the strip, not against it */
.nz-ptabs26 > .tab-content {
    padding: 20px 16px 16px;
}

/* --- a pane that is one card merges into the shell -------------------
   Most tabs (tasks, notes, files, invoices, …) are a single `.card`
   holding a title bar and an appTable. Inside the shell that card is a
   second box around the first, so it gives up everything that makes it
   a box and keeps only its contents.

   `> .card` and not a descendant selector: the Overview's widgets, the
   timesheet sub-tabs' inner cards and every appTable's own panels are
   deeper than this and must keep their own surface. */
.nz-ptabs26 > .tab-content > .tab-pane > .card {
    margin: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
}

/* A pane that opens with its OWN tab strip (Files, Timesheets) draws a
   second bordered, rounded top edge right under the shell's. Same
   treatment: it keeps being a strip, it stops being the top of a box. */
.nz-ptabs26 > .tab-content > .tab-pane > div > .nav-tabs.title,
.nz-ptabs26 > .tab-content > .tab-pane > div > .nav-tabs.bg-white,
.nz-ptabs26 > .tab-content > .tab-pane > .card > .nav-tabs.title,
.nz-ptabs26 > .tab-content > .tab-pane > .card > .nav-tabs.bg-white {
    border: 0 !important;
    border-radius: 0 !important;
    background: transparent !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    padding-left: 0;
    padding-right: 0;
    box-shadow: none !important;
}

/* the flattened card's own header keeps its hairline — it is still the
   pane's title bar, it is just no longer the top of a box */
.nz-ptabs26 > .tab-content > .tab-pane > .card > .card-header,
.nz-ptabs26 > .tab-content > .tab-pane > .card > .tab-title,
.nz-ptabs26 > .tab-content > .tab-pane > .card > .title-tab {
    padding-top: 0;
    padding-left: 0;
    padding-right: 0;
    background: transparent !important;
}

/* a pane whose first child is a table rather than a title bar sits
   straight under the strip; the shell's own padding is its margin */
.nz-ptabs26 > .tab-content > .tab-pane > .card > .table-responsive:first-child {
    margin-top: 0;
}

/* --- the Overview pane ----------------------------------------------
   Its bands already carry their own bottom padding and the shell has
   its own, so the last band would sit on 44px of air. */
.nz-ptabs26 > .tab-content > .tab-pane > .nz-dash26 {
    padding-bottom: 4px;
}

/* the first band heading has the shell's padding above it already */
.nz-ptabs26 > .tab-content > .tab-pane > .nz-dash26 > .nz-dash-section:first-child {
    margin-top: 0;
}

/* --- the strip itself ------------------------------------------------
   `nav-tabs rounded classic` is the app's own pill strip and keeps the
   shared iOS 26 glider (assets/js/ios26-tabs.js) and the overflow
   arrows (assets/js/tabs-scroller.js). All that changes here is that it
   now sits ON something. */
.nz-ptabs26 > .nav-tabs::-webkit-scrollbar {
    height: 0;
}

@media (max-width: 575px) {
    .nz-ptabs26 > .tab-content {
        padding: 16px 10px 12px;
    }

    .nz-ptabs26 > .nav-tabs,
    .nz-ptabs26 > .nz-tabscroll > .nav-tabs {
        padding-block: 10px 12px;
    }

    .nz-ptabs26 > .nav-tabs {
        padding-inline: 8px;
    }
}
