/* Portal layer "float": tiles look like solid slabs floating above the page. A layer, not a style: it loads
   after portal.css (and after the base style's sheet, e.g. portal-command.css) and before the style that lists
   it, and every rule is scoped to html.pt-float.

   CONTRACT for styles built on this layer (set these on your own html.pt-<key>; defaults below):
     --fl-rgb       shadow tint as "r, g, b"                        (16, 24, 40)
     --fl-edge      the slab's visible bottom edge (its thickness)  (#d5dbe5, a darker shade of the card)
     --fl-hi        top highlight line                              (rgba(255, 255, 255, .9))
     --fl-lift      hover lift of small tiles                       (6px)
     --fl-strength  shadow opacity multiplier, 0..2                 (1)
   Tiles:
     big   .p-card (incl. .p-table-card, Today/client [data-tile] cards), .p-filters, .p-map-results:
           3px slab + soft shadows, NEVER a transform (they hold maps, dialogs, tables; see below).
     small .p-lead, .p-today-stat, .p-price, .p-plan: 4px slab + two soft shadows; on hover they lift
           (translateY(-var(--fl-lift)) + perspective tilt) and the far shadow grows; link tiles
           (a.p-today-stat, a.p-price) press down 2px on :active.
           .p-balance-card is a .p-card: it gets the small slab but no lift.
     keys  .p-btn-primary 3px key edge (cta darkened); .p-btn 2px edge; both press down on :active.
     pills .p-chips a, .p-tabs a: 1px edge only.
   Each tile's shadow stack is in --fl-sh (set on the tile itself), so state rings can be prepended:
     box-shadow: 0 0 0 2px <ring>, var(--fl-sh);
   Never add transform / filter / will-change / backdrop-filter to .p-top (fixed sidebar, holds the fixed
   .p-help-menu), .p-card / .p-table-card / [data-tile] (dialogs, Leaflet maps), .p-map, .p-bulk, .p-install,
   the tour (.p-tour-*), or a dialog's ancestors: a transform turns position:fixed children into
   absolute ones. Tables inside cards stay flat. */

html.pt-float {
  --fl-rgb: 16, 24, 40;
  --fl-edge: #d5dbe5;
  --fl-hi: rgba(255, 255, 255, .9);
  --fl-lift: 6px;
  --fl-strength: 1;
  --fl-ease: cubic-bezier(.2, .8, .2, 1);
}

/* ---- Big cards: resting slab only, no transform, no hover change ---- */
.pt-float .p-card, .pt-float .p-filters, .pt-float .p-map-results {
  --fl-far: 0 30px 50px -20px;
  --fl-far-a: .22;
  --fl-sh: inset 0 1px 0 var(--fl-hi),
    0 1px 0 var(--fl-edge), 0 2px 0 var(--fl-edge), 0 3px 0 var(--fl-edge),
    0 10px 16px -8px rgba(var(--fl-rgb), calc(.18 * var(--fl-strength))),
    var(--fl-far) rgba(var(--fl-rgb), calc(var(--fl-far-a) * var(--fl-strength)));
  box-shadow: var(--fl-sh);
}
.pt-float .p-card { margin-bottom: 20px; }
.pt-float .p-grid-2 .p-card, .pt-float .p-import-grid .p-card { margin-bottom: 0; }
.pt-float .p-filters { margin-bottom: 22px; }

/* ---- Small tiles: resting slab ---- */
.pt-float .p-lead, .pt-float .p-today-stat, .pt-float .p-price, .pt-float .p-plan, .pt-float .p-card.p-balance-card {
  --fl-far: 0 30px 50px -20px;
  --fl-far-a: .30;
  --fl-slab: 0 1px 0 var(--fl-edge), 0 2px 0 var(--fl-edge), 0 3px 0 var(--fl-edge), 0 4px 0 var(--fl-edge);
  --fl-sh: inset 0 1px 0 var(--fl-hi), var(--fl-slab),
    0 10px 16px -8px rgba(var(--fl-rgb), calc(.28 * var(--fl-strength))),
    var(--fl-far) rgba(var(--fl-rgb), calc(var(--fl-far-a) * var(--fl-strength)));
  box-shadow: var(--fl-sh);
}
.pt-float .p-lead, .pt-float .p-today-stat, .pt-float .p-price, .pt-float .p-plan {
  transition: transform .22s var(--fl-ease), box-shadow .22s var(--fl-ease), opacity .3s;
}
/* Room for the slab edge and the shadows between neighbours */
.pt-float .p-grid { gap: 18px; }
.pt-float .p-today-stats, .pt-float .p-results-stats { gap: 16px; margin-bottom: 22px; }
.pt-float .p-prices { gap: 14px; margin-bottom: 20px; }
.pt-float .p-plans { gap: 20px; margin-bottom: 20px; }

/* Softer borders (the slab and shadows do the separating). Only where color-mix works: inside a var() it
   would otherwise fail at computed time and fall back to currentColor. */
@supports (color: color-mix(in srgb, red 50%, blue)) {
  /* :where() keeps this at the plain tile's weight and skips tiles whose state sets its own border colour.
     A base style's left accent (e.g. Command's .p-today-stat) is softened too: restate it in your style. */
  .pt-float .p-card:where(:not(.p-invite)), .pt-float .p-filters, .pt-float .p-map-results, .pt-float .p-today-stat,
  .pt-float .p-lead:where(:not(.p-picked, .p-focus)), .pt-float .p-price:where(:not(.on)),
  .pt-float .p-plan:where(:not(.p-plan-featured, .p-plan-current)) {
    border-color: color-mix(in srgb, var(--line) 60%, transparent);
  }
  .pt-float .p-price:hover { border-color: var(--navy-2); }
}

/* State rings sit on top of the slab */
.pt-float .p-price.on { box-shadow: inset 0 0 0 1px var(--navy-2), var(--fl-sh); }
.pt-float .p-lead.p-picked { box-shadow: 0 0 0 2px rgba(20, 122, 75, .25), var(--fl-sh); }
.pt-float .p-lead.p-focus { box-shadow: 0 0 0 3px rgba(217, 45, 32, .25), var(--fl-sh); }

/* ---- Small tiles: hover lift (pointer devices only, so a tap does not leave a tile stuck up) ---- */
@media (hover: hover) {
  .pt-float .p-lead:hover, .pt-float .p-today-stat:hover, .pt-float .p-price:hover, .pt-float .p-plan:hover {
    --fl-far: 0 44px 64px -22px;
    --fl-far-a: .36;
    transform: perspective(900px) rotateX(2deg) translateY(calc(-1 * var(--fl-lift)));
  }
}
/* Press: only tiles that are links (a lead card is not; pressing its Buy button presses the button) */
.pt-float a.p-today-stat:active, .pt-float a.p-price:active {
  --fl-slab: 0 1px 0 var(--fl-edge), 0 2px 0 var(--fl-edge);
  --fl-far: 0 18px 30px -16px;
  --fl-far-a: .24;
  transform: translateY(2px);
}

/* ---- Buttons: keys with a raised edge ---- */
.pt-float .p-btn {
  box-shadow: inset 0 1px 0 var(--fl-hi), 0 2px 0 var(--fl-edge), 0 4px 8px -4px rgba(var(--fl-rgb), calc(.25 * var(--fl-strength)));
  transition: transform .12s var(--fl-ease), box-shadow .12s var(--fl-ease), background-color .15s, border-color .15s;
}
.pt-float .p-btn:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: inset 0 1px 0 var(--fl-hi), 0 1px 0 var(--fl-edge), 0 2px 4px -2px rgba(var(--fl-rgb), calc(.2 * var(--fl-strength)));
}
.pt-float .p-btn-primary {
  --fl-key: rgba(0, 0, 0, .28);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), 0 3px 0 var(--fl-key), 0 8px 14px -6px rgba(var(--fl-rgb), calc(.4 * var(--fl-strength)));
}
@supports (color: color-mix(in srgb, red 50%, blue)) {
  .pt-float .p-btn-primary { --fl-key: color-mix(in srgb, var(--cta) 70%, black); }
}
.pt-float .p-btn-primary:active:not(:disabled) {
  transform: translateY(2px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), 0 1px 0 var(--fl-key), 0 3px 6px -3px rgba(var(--fl-rgb), calc(.3 * var(--fl-strength)));
}
.pt-float .p-btn:disabled { box-shadow: none; }

/* ---- Pills: a hairline edge, no motion ---- */
.pt-float .p-chips > a:not(.p-switch), .pt-float .p-tabs a {
  box-shadow: 0 1px 0 var(--fl-edge), 0 3px 6px -4px rgba(var(--fl-rgb), calc(.2 * var(--fl-strength)));
}

/* ---- Phones: same slab, a shorter far shadow so stacked tiles do not muddy together ---- */
@media (max-width: 759px) {
  .pt-float .p-card, .pt-float .p-filters, .pt-float .p-map-results,
  .pt-float .p-lead, .pt-float .p-today-stat, .pt-float .p-price, .pt-float .p-plan {
    --fl-far: 0 16px 26px -14px;
    --fl-far-a: .18;
  }
}

/* ---- Reduced motion: keep the depth, drop the movement ---- */
@media (prefers-reduced-motion: reduce) {
  .pt-float .p-lead, .pt-float .p-today-stat, .pt-float .p-price, .pt-float .p-plan, .pt-float .p-btn { transition: none; }
  .pt-float .p-lead:hover, .pt-float .p-today-stat:hover, .pt-float .p-price:hover, .pt-float .p-plan:hover,
  .pt-float a.p-today-stat:active, .pt-float a.p-price:active, .pt-float .p-btn:active { transform: none !important; }
}
