{"version":3,"file":"blocks/Tabs/style-index.css","mappings":";;;AAAA,gBAAgB;ACAhB;;;;;;;;;;;;;EAAA;AAeA;;;;;;;;;;EAAA;AAgBA;;;;;;;;;EAAA;AAgBA;;;;;;;;;;EAAA;AD7CA;;;;;;;;;;EAAA;AAoBA;;;;;EAAA;AAQA;EACE;EACA;EACA;;;;mDAAA;EAKA;AAmCF;AA/BI;EACE;AAiCN;AA9BI;EACE;AAgCN;AA3BE;EACE;EACA;EACA;;;;4EAAA;EAKA;AA6BJ;AAzBE;EACE;AA2BJ;AAxBE;EACE;EACA;AA0BJ;AAtBE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;wCAAA;EAGA;AAwBJ;AAtBI;;EAEE;AAwBN;AA9CE;EAyBE;wEAAA;AAyBJ;AAvBI;EACE;AAyBN;AAtBI;EACE;AAwBN;AArBI;EACE;AAuBN;AAvGA;EAoFE;;;6CAAA;AAyBF;AArBE;EACE,aA3Fe;AAkHnB;AAnBE;EACE;EACA;EACA;EACA;AAqBJ;AAjBE;EACE;AAmBJ;AAjBI;EACE;AAmBN;AANI;EACE;AAQN;AALI;EACE;EACA;AAON;AALM;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAOR;AAJM;EACE;AAMR;AAHM;EACE;AAKR;AAcI;EACE;AAZN;AAeI;EACE;EACA;AAbN;AAeM;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAbR;AAgBM;EACE;AAdR;AAiBM;EACE;AAfR;AAsBI;EACE;EACA;EACA;AApBN;AAsBM;EACE;EACA;AApBR;AAuBM;EACE;EACA;AArBR;AA0CI;EACE;AAxCN;AA0CM;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAIA;EACA;EACA;EACA;EAEA;;;;IAAA;EAKA;AA5CR;AAoBI;EA2BE;;;;;;IAAA;AAtCN;AA6CM;EACE,mJACE;AA5CV;AAiDM;EACE;IACE;EA/CR;AACF;AAmDI;EAGE;EACA;EACA;AAnDN;AAqDM;EACE;EACA;AAnDR;AAyDE;EACE;AAvDJ;AAyDI;EACE;EACA;EACA;AAvDN;AA0DI;EACE;EACA;AAxDN;AA0DM;EACE;EACA;AAxDR;AA2EE;EACE;AAzEJ;AA2EI;EACE;EACA;EACA;EACA;EAEA;;;;;;;;;IAAA;EAUA;EAAA;EACA;AA1EN;AA8EI;EACE;AA5EN;AA+EI;EACE;AA7EN;AAkFI;EACE;AAhFN;AAmFI;EACE;EACA;AAjFN;AAmFM;EACE;EACA;AAjFR;AAoGI;EACE;AAlGN;AAqGI;EACE;AAnGN;AAwGE;EAEE;EACA;AAvGJ;AAyGI;EACE;EACA;;8BAAA;EAGA;EACA;EACA;EACA;EACA;;;yDAAA;EAIA;EAAA;AAvGN;AA6GI;EACE;EACA;AA3GN;AA8GI;EACE;EACA;AA5GN;AAiHI;EACE;AA/GN;AAkHI;EACE;AAhHN;AAyHM;EACE;EACA;AAvHR;AA0HM;EACE;EACA;AAxHR;AA0HQ;EACE;EACA;EACA;EACA;EACA;EACA;AAxHV;AAmIM;EACE;EACA;AAjIR;AAoIM;EACE;EACA;AAlIR;AAoIQ;EACE;EACA;EACA;EACA;EACA;EACA;AAlIV;AA0II;EACE;EACA;AAxIN;AA2II;EACE;EACA;AAzIN;AA8IE;EACE;IACE;EA5IJ;EA8II;IACE;EA5IN;AACF;AAiJE;EACE;EACA;AA/IJ;;AAkJA;;;;;;;;;;gFAAA;AAWA;EACE;;IAEE;IACA;wEAAA;IAEA;IACA,kFACE;IAEF;IACA;EAjJF;EAoJA;IACE,kFACE;EAnJJ;EAuJA;IACE;EArJF;EAwJA;IACE;EAtJF;EAyJA;;;;;;IAAA;EAOA;;IAEE;IACA;EAvJF;EA0JA;;;;;;;;;;;;;;;;;;IAAA;EAqBE;;;;;;ICvkBF;IACA;IACA;IAhBA;EDocA;EAyJE;;IC/kBF;IACA;IACA;ED0bA;EC3aA;IACE;IACA,cDkkBuC;EArJzC;EC1aA;IACE;IACA,cD6jB0C;EAjJ5C;ECnbA;IACE;IACA,cDskBuC;EAjJzC;EClbA;IACE;IACA,cDikB0C;EA7I5C;EAgJA;;;;;;;;;;;;;;;;IAAA;EAiBA;;;;uDAAA;EAOE;;IACE;IACA;;6DAAA;IAGA;IACA;EA/IJ;EAkJE;;IACE;EA/IJ;EAiJI;;IACE;IACA;IACA;EA9IN;EAmJA;;;6EAAA;EAME;;IACE;IACA;IACA;EAlJJ;EAsJA;+EAAA;EAEA;IACE;;MAEE;MACA;MACA;;;wCAAA;MAIA;IApJF;IAuJA;;MAEE;;;oEAAA;IAlJF;IAsJE;;MACE;MACA;IAnJJ;IAsJE;;MACE;MACA;MACA;IAnJJ;IAsJE;;MACE;IAnJJ;IAsJE;;;;MAEE;MACA;IAlJJ;IAqJE;;MACE;IAlJJ;EACF;AACF;AAsJA;;;;;;;;;;;;;6EAAA;AAeA;EACE;EACA;EACA;AArJF;AAuJE;EACE;AArJJ;;AAyJA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gFAAA;AAkCA;+EAAA;AASA;EACE;IACE;;6CAAA;IAGA;IACA;IACA;;;;;yBAAA;IAMA;IACA;IACA;;sEAAA;IAGA;EA9JF;EAkKE;IACE;IACA;EAhKJ;EAmKE;IACE;IACA;EAjKJ;EAoKE;IACE;IACA;EAlKJ;EAsJE;IACE;IACA;EApJJ;EAuJE;IACE;IACA;EArJJ;EAwJE;IACE;IACA;EAtJJ;EA0IE;IACE;IACA;EAxIJ;EA2IE;IACE;IACA;EAzIJ;EA4IE;IACE;IACA;EA1IJ;EA8HE;IACE;IACA;EA5HJ;EA+HE;IACE;IACA;EA7HJ;EAgIE;IACE;IACA;EA9HJ;EAkIA;;;;;;yDAAA;EAQE;IACE;IACA;EAjIJ;EAoIE;IACE;EAlIJ;EAsIA;;;;8EAAA;EAME;IACE;IACA;IACA;IACA;IACA;EArIJ;EAuII;IACE;IACA;IACA;IACA;EArIN;EA0IA;;;;;;+DAAA;EAOA;IACE;MAGE;IA1IF;EACF;EA6IA;4EAAA;EAEA;;IAEE;IACA;IACA;IACA;wCAAA;IAEA;EA3IF;EA8IA;IACE;EA5IF;EA+IA;IACE;EA7IF;EAgJA;IACE;MACE;MACA;IA9IF;IAiJA;MACE;MACA;IA/IF;IAkJA;MACE;MACA;IAhJF;EACF;EAmJA;;;;;;;;;;;;;;+BAAA;EAeA;IAGE;EAnJF;EAoJE;;IAEE;IACA;IACA;EAlJJ;EAqJE;IACE;IACA;EAnJJ;EAsJE;IACE;IACA;EApJJ;EAwJA;IAIE;IACA;EAzJF;EA4JA;;;gFAAA;EAKE;IACE;EA3JJ;EA8JE;IACE;EA5JJ;EAiKE;IACE;EA/JJ;EAkKE;IACE;EAhKJ;AACF,C","sources":["webpack://brandy-blocks/./src/blocks/Tabs/style.scss","webpack://brandy-blocks/./src/blocks/Tabs/_layout-presets.scss"],"sourcesContent":["@import 'layout-presets';\n\n/*\n * Default palette for the Tabs block.\n *\n * Each default resolves to a Brandy design token first (registered by the theme\n * as `--wp--preset--color--brandy-*`). Themes without those tokens fall back to\n * a WordPress core preset where one fits, and otherwise to the literal colour\n * the block shipped with, so appearance outside a Brandy theme is unchanged.\n *\n * These are defaults only — the block's own colour attributes still override\n * them through the `--tab-*` custom properties set in render.php.\n */\n$tab-accent: var(--wp--preset--color--brandy-primary, #007cba);\n$tab-foreground: var(--wp--preset--color--brandy-foreground, #09090b);\n$tab-muted: var(--wp--preset--color--brandy-muted-foreground, #6b7280);\n$tab-border: var(--wp--preset--color--brandy-border, #e0e0e0);\n$tab-surface: var(--wp--preset--color--brandy-gray-2, #f4f4f5);\n$tab-raised: var(--wp--custom--color--background, #fff);\n$tab-on-accent: var(--wp--preset--color--white, #fff);\n$tab-tint: var(--wp--preset--color--brandy-primary-10, rgba(0, 0, 0, 0.05));\n\n/*\n * How far unselected tabs fade when \"Dim inactive tabs\" is on. A fixed token\n * rather than an author control, for the same reason the content animations\n * keep their duration and easing here: it is a design decision, not a\n * per-instance one.\n */\n$tab-inactive-dim: 0.45;\n\n.wp-block-brandy-tabs {\n  display: flex;\n  flex-direction: column;\n  /* Separates the nav from the panels — the only two children — in whichever\n     direction the position puts them. The panels' own padding sits inside the\n     panel, so without this the nav butts straight up against the panel box and\n     a vertical nav's divider touches the content it is dividing. Side layouts\n     override this with their own `--region-gap`. */\n  gap: var(--tabs-nav-gap, 16px);\n\n  // Tab position bottom = reverse order\n  &.tab-position-bottom {\n    .brandy-tabs__nav {\n      order: 2;\n    }\n\n    .brandy-tabs__panels {\n      order: 1;\n    }\n  }\n\n  // Tab nav bar\n  .brandy-tabs__nav {\n    display: flex;\n    gap: var(--tab-gap, 0px);\n    /* Tabs are `white-space: nowrap` and image tabs can be far wider still — a\n       row of wordmark logos runs well past a phone viewport. Without wrapping\n       the row cannot shrink below its content, so it either overflows or\n       squeezes each logo into an illegible sliver. Wrapping only engages once\n       the row genuinely does not fit, so rows that fit today are untouched. */\n    flex-wrap: wrap;\n  }\n\n  // Tab alignment\n  &.tab-align-center .brandy-tabs__nav {\n    justify-content: center;\n  }\n\n  &.tab-align-stretch .brandy-tabs__nav .brandy-tabs__tab {\n    flex: 1;\n    text-align: center;\n  }\n\n  // Tab buttons\n  .brandy-tabs__tab {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    cursor: pointer;\n    padding: 10px 20px;\n    border: none;\n    background: transparent;\n    color: var(--tab-inactive-color, #{$tab-muted});\n    font-size: inherit;\n    font-family: inherit;\n    font-weight: 500;\n    line-height: 1.5;\n    transition: all 0.2s ease;\n    white-space: nowrap;\n    /* A linked tab renders as an anchor, and this block ships to themes that\n       underline links. The rest of this rule is a button reset; this is the\n       matching one for the anchor case. */\n    text-decoration: none;\n\n    img,\n    i {\n      flex-shrink: 0;\n    }\n\n    /* An image sized by height under `contain` has no width bound of its own,\n       so cap it before a wide logo can push past the tab it belongs to. */\n    img {\n      max-width: 100%;\n    }\n\n    &:hover {\n      color: var(--tab-hover-color, var(--tab-active-color, #{$tab-accent}));\n    }\n\n    &.is-active {\n      color: var(--tab-active-color, #{$tab-accent});\n    }\n  }\n\n  /* Fades the whole unselected tab — logo, icon and label together — so a strip\n     of brand marks reads as one selected item and the rest receding. Riding on\n     the button rather than its image also picks up the `transition` above, so\n     the change eases rather than snapping. */\n  &.dim-inactive-tabs .brandy-tabs__tab:not(.is-active) {\n    opacity: $tab-inactive-dim;\n  }\n\n  // Tab panels\n  .brandy-tabs__panels {\n    padding-top: var(--content-padding-top, 20px);\n    padding-right: var(--content-padding-right, 20px);\n    padding-bottom: var(--content-padding-bottom, 20px);\n    padding-left: var(--content-padding-left, 20px);\n  }\n\n  // Only target render.php wrapper (direct child), not nested save.jsx div\n  .brandy-tabs__panel {\n    display: none;\n\n    &.is-active {\n      display: block;\n    }\n  }\n\n  // === Style: Underline (edge) ===\n  //\n  // The marker sits on the edge the nav shares with the panels, which is why\n  // the positional variants further down move it: bottom becomes top when the\n  // nav is below, and a left or right position turns it into a rule down the\n  // side of the nav rather than an underline. `underline-below` is the style\n  // for keeping a real underline in those positions.\n  &.is-style-underline,\n  &:not([class*=\"is-style-\"]) {\n    .brandy-tabs__nav {\n      border-bottom: 1px solid #{$tab-border};\n    }\n\n    .brandy-tabs__tab {\n      position: relative;\n      padding-bottom: 12px;\n\n      &::after {\n        content: \"\";\n        position: absolute;\n        bottom: -1px;\n        left: 0;\n        right: 0;\n        height: 2px;\n        background: transparent;\n        transition: background 0.2s ease;\n      }\n\n      &.is-active::after {\n        background: var(--tab-active-color, #{$tab-accent});\n      }\n\n      &:hover:not(.is-active)::after {\n        background: var(--tab-hover-color, var(--tab-active-color, #{$tab-accent}));\n      }\n    }\n  }\n\n  // === Style: Underline (below label) ===\n  //\n  // Same marker, anchored to the label instead of to the nav's edge, so it\n  // stays a horizontal bar under each tab whichever side the nav is on — the\n  // only way an underline survives a vertical nav.\n  //\n  // No divider on the nav either: with the bars no longer sitting on that\n  // line, a rule down the side of a vertical nav is just a second line with\n  // nothing to do, and dropping it is what makes this read as a set of\n  // underlined labels rather than a sidebar.\n  //\n  // None of the positional variants below match this style, so `bottom: 0`\n  // holds in all four positions without needing to be restated.\n  &.is-style-underline-below {\n    .brandy-tabs__nav {\n      border: 0;\n    }\n\n    .brandy-tabs__tab {\n      position: relative;\n      padding-bottom: 12px;\n\n      &::after {\n        content: \"\";\n        position: absolute;\n        right: 0;\n        bottom: 0;\n        left: 0;\n        height: 2px;\n        background: transparent;\n        transition: background 0.2s ease;\n      }\n\n      &.is-active::after {\n        background: var(--tab-active-color, #{$tab-accent});\n      }\n\n      &:hover:not(.is-active)::after {\n        background: var(--tab-hover-color, var(--tab-active-color, #{$tab-accent}));\n      }\n    }\n  }\n\n  // === Style: Pills ===\n  &.is-style-pills {\n    .brandy-tabs__tab {\n      border-radius: 999px;\n      padding: 8px 20px;\n      background: var(--tab-inactive-bg, transparent);\n\n      &.is-active {\n        background: var(--tab-active-bg, #{$tab-accent});\n        color: var(--tab-active-color, #{$tab-on-accent});\n      }\n\n      &:hover:not(.is-active) {\n        color: var(--tab-hover-color, var(--tab-inactive-color, #{$tab-muted}));\n        background: var(--tab-hover-bg, #{$tab-tint});\n      }\n    }\n  }\n\n  // === Style: Boxed (shadcn/Radix) ===\n  // === Sliding marker, shared by Boxed and Segmented ===\n  //\n  // Both styles mark the selection with a raised block sitting on a track, so\n  // both animate it the same way: one element that slides and resizes between\n  // tabs instead of a background blinking from one to the next.\n  //\n  // The marker is `::before` on the nav rather than a real element, so no\n  // markup changes and no other style is affected. `view.js` measures the\n  // active tab and writes the four geometry properties; everything else is CSS.\n  // Only the corner radius differs between the two, via --tab-marker-radius.\n  //\n  // Measured off the reference: 260ms, position and width moving together, no\n  // overshoot — so a transition is enough and no animation loop is needed.\n  &.is-style-boxed,\n  &.is-style-segmented {\n    .brandy-tabs__nav {\n      position: relative;\n\n      &::before {\n        content: '';\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: var(--tab-indicator-w, 0);\n        height: var(--tab-indicator-h, 0);\n        transform: translate(\n          var(--tab-indicator-x, 0),\n          var(--tab-indicator-y, 0)\n        );\n        background: var(--tab-active-bg, #{$tab-raised});\n        border-radius: var(--tab-marker-radius, 6px);\n        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n        z-index: 0;\n\n        /*\n         * No transition until the first measurement has landed, or the marker\n         * animates in from the nav's top-left corner on every page load.\n         * view.js adds the class once it has written real geometry.\n         */\n        transition: none;\n      }\n\n      /*\n       * Ease-in-out, not ease-out. The reference's marker leaves gently, peaks\n       * mid-travel and settles — an S-curve, measured at roughly 3% of the\n       * distance covered in the first fifth of the time. An ease-out curve\n       * spends that same fifth covering a quarter of the distance, which reads\n       * as a snap followed by a crawl.\n       */\n      &.has-indicator-ready::before {\n        transition:\n          transform 260ms cubic-bezier(0.65, 0, 0.35, 1),\n          width 260ms cubic-bezier(0.65, 0, 0.35, 1),\n          height 260ms cubic-bezier(0.65, 0, 0.35, 1);\n      }\n\n      @media (prefers-reduced-motion: reduce) {\n        &.has-indicator-ready::before {\n          transition: none;\n        }\n      }\n    }\n\n    .brandy-tabs__tab {\n      // Above the marker, and transparent so the marker is what reads as the\n      // selection — the tab itself never paints a background.\n      position: relative;\n      z-index: 1;\n      background: transparent;\n\n      &.is-active {\n        background: transparent;\n        color: var(--tab-active-color, #{$tab-foreground});\n      }\n    }\n  }\n\n  // === Style: Boxed (shadcn/Radix) ===\n  &.is-style-boxed {\n    --tab-marker-radius: 6px;\n\n    .brandy-tabs__nav {\n      background: var(--tab-inactive-bg, #{$tab-surface});\n      border-radius: 8px;\n      padding: 4px;\n    }\n\n    .brandy-tabs__tab {\n      border-radius: 6px;\n      padding: 8px 16px;\n\n      &:hover:not(.is-active) {\n        color: var(--tab-hover-color, var(--tab-inactive-color, #{$tab-muted}));\n        background: var(--tab-hover-bg, #{$tab-tint});\n      }\n    }\n  }\n\n  // === Style: Segmented (iOS-style control with a sliding indicator) ===\n  //\n  // Boxed's track, fully rounded, plus one thing none of the other styles have:\n  // the selected marker is a single element that slides and resizes between\n  // tabs instead of a background that blinks from one to the next.\n  //\n  // The marker is `::before` on the nav rather than a real element, so no\n  // markup changes and no other style is affected. `view.js` measures the\n  // active tab and writes the four geometry properties below; everything else\n  // is CSS.\n  //\n  // Measured off the reference: 250ms, decelerating, position and width moving\n  // together, no overshoot — so a transition is enough and no animation loop is\n  // needed.\n  &.is-style-segmented {\n    --tab-marker-radius: 999px;\n\n    .brandy-tabs__nav {\n      background: var(--tab-inactive-bg, #{$tab-surface});\n      border-radius: 999px;\n      padding: 4px;\n      gap: var(--tab-gap, 0px);\n\n      /*\n       * A segmented control is a pill around its own tabs, not a full-width\n       * bar — left to stretch, the track runs the width of the container and\n       * strands the marker at one end. Alignment then has to come from the\n       * margin, since `justify-content` has nothing to distribute once the\n       * box is only as wide as its content.\n       *\n       * Boxed deliberately keeps the container's width: it already ships that\n       * way, and narrowing it would move every existing instance.\n       */\n      width: fit-content;\n      max-width: 100%;\n    }\n\n    // Alignment, restated for a shrink-wrapped track.\n    &.tab-align-center .brandy-tabs__nav {\n      margin-inline: auto;\n    }\n\n    &.tab-align-end .brandy-tabs__nav {\n      margin-inline-start: auto;\n    }\n\n    // Stretch asks tabs to divide the full row, which is the one case where the\n    // track does want the container's width.\n    &.tab-align-stretch .brandy-tabs__nav {\n      width: 100%;\n    }\n\n    .brandy-tabs__tab {\n      border-radius: 999px;\n      padding: 6px 16px;\n\n      &:hover:not(.is-active) {\n        color: var(--tab-hover-color, var(--tab-inactive-color, #{$tab-muted}));\n        background: transparent;\n      }\n    }\n  }\n\n  // === Style: Minimal (no selected indicator) ===\n  //\n  // Nothing marks the active tab but its colour: no bar, no pill, no box, and\n  // no rule dividing the nav from the panels.\n  //\n  // Carrying an `is-style-` class is already most of the work, since the\n  // underline rules match `:not([class*=\"is-style-\"])` and so stop applying the\n  // moment any style is picked. The two declarations below are the style's\n  // contract stated outright rather than left to depend on which selectors\n  // happen not to match — a marker added to the base button later would\n  // otherwise reappear here, which is the one thing this style promises not to\n  // have. Positional variants only reposition `::after`, so suppressing the\n  // pseudo-element covers every orientation and position at once.\n  &.is-style-minimal {\n    .brandy-tabs__nav {\n      border: 0;\n    }\n\n    .brandy-tabs__tab::after {\n      content: none;\n    }\n  }\n\n  // Vertical layout (left / right positions)\n  &.tab-position-left,\n  &.tab-position-right {\n    flex-direction: row;\n    align-items: flex-start;\n\n    .brandy-tabs__nav {\n      flex-direction: column;\n      /* A column that wrapped would spill into a second column beside the\n         panel rather than growing downwards, so the horizontal row's wrapping\n         is explicitly off here. */\n      flex-wrap: nowrap;\n      flex-shrink: 0;\n      margin-bottom: 0;\n      width: var(--trigger-width, 120px);\n      /* Tab labels are `white-space: nowrap`, so a fixed width does not\n         truncate them — it lets them spill over the panel beside it. Growing\n         the column to its widest label keeps the set width as a floor for\n         short labels while guaranteeing nothing overflows. */\n      min-width: max-content;\n    }\n\n    // Vertical tabs read like a sidebar nav — left-align labels so long\n    // names don't look adrift in a narrow column. Overrides the horizontal\n    // default (center) inherited from .brandy-tabs__tab.\n    .brandy-tabs__nav .brandy-tabs__tab {\n      justify-content: flex-start;\n      text-align: left;\n    }\n\n    .brandy-tabs__panels {\n      flex: 1;\n      min-width: 0;\n    }\n  }\n\n  &.tab-position-right {\n    .brandy-tabs__nav {\n      order: 2;\n    }\n\n    .brandy-tabs__panels {\n      order: 1;\n    }\n  }\n\n  // Underline — left position: border on right of nav, indicator on right of tab\n  &.tab-position-left {\n\n    &.is-style-underline,\n    &:not([class*=\"is-style-\"]) {\n      .brandy-tabs__nav {\n        border-bottom: none;\n        border-right: 1px solid #{$tab-border};\n      }\n\n      .brandy-tabs__tab {\n        padding-bottom: 10px;\n        padding-right: 12px;\n\n        &::after {\n          top: 0;\n          bottom: 0;\n          right: -1px;\n          left: auto;\n          width: 2px;\n          height: auto;\n        }\n      }\n    }\n  }\n\n  // Underline — right position: border on left of nav, indicator on left of tab\n  &.tab-position-right {\n\n    &.is-style-underline,\n    &:not([class*=\"is-style-\"]) {\n      .brandy-tabs__nav {\n        border-bottom: none;\n        border-left: 1px solid #{$tab-border};\n      }\n\n      .brandy-tabs__tab {\n        padding-bottom: 10px;\n        padding-left: 12px;\n\n        &::after {\n          top: 0;\n          bottom: 0;\n          left: -1px;\n          right: auto;\n          width: 2px;\n          height: auto;\n        }\n      }\n    }\n  }\n\n  // Tab position bottom: flip underline border\n  &.tab-position-bottom.is-style-underline {\n    .brandy-tabs__nav {\n      border-bottom: none;\n      border-top: 1px solid #{$tab-border};\n    }\n\n    .brandy-tabs__tab::after {\n      bottom: auto;\n      top: -1px;\n    }\n  }\n\n  // Reduced motion\n  @media (prefers-reduced-motion: reduce) {\n    .brandy-tabs__tab {\n      transition: none;\n\n      &::after {\n        transition: none;\n      }\n    }\n  }\n\n  // Focus styles\n  .brandy-tabs__tab:focus-visible {\n    outline: 2px solid #{$tab-accent};\n    outline-offset: 2px;\n  }\n}\n/* ---------------------------------------------------------------------------\n   Layout presets.\n\n   `classic` is the historical flex layout and is styled above; nothing here\n   applies to it. The side presets turn the root into a grid and place the tab's\n   regions into it.\n\n   Everything sits inside `@supports (grid-template-columns: subgrid)`. Without\n   subgrid the rules simply never apply and the block falls back to the classic\n   flex layout with the regions stacked in source order — degraded, but intact.\n   --------------------------------------------------------------------------- */\n@supports (grid-template-columns: subgrid) {\n  .brandy-tabs.layout-side-right,\n  .brandy-tabs.layout-side-left {\n    display: grid;\n    /* Row 1 is the nav's band, row 2 takes the remaining height. The side\n       region spans both, which is what lets it sit alongside the nav. */\n    grid-template-rows: auto 1fr;\n    grid-template-columns:\n      var(--region-main-width, 1fr)\n      var(--region-side-width, 1fr);\n    align-items: start;\n    gap: var(--region-gap, 40px);\n  }\n\n  .brandy-tabs.layout-side-left {\n    grid-template-columns:\n      var(--region-side-width, 1fr)\n      var(--region-main-width, 1fr);\n  }\n\n  .layout-side-right > .brandy-tabs__nav {\n    grid-area: 1 / 1;\n  }\n\n  .layout-side-left > .brandy-tabs__nav {\n    grid-area: 1 / 2;\n  }\n\n  /*\n   * The panels' pass-through below spans the whole grid, nav row included, and\n   * the panels are the later sibling — so their (transparent) wrappers paint\n   * and hit-test above the nav, swallowing every click meant for a tab. Lift\n   * the nav above the overlay; the wrappers have nothing of their own to show\n   * in the nav's cell, so nothing is hidden by it.\n   */\n  .layout-side-right > .brandy-tabs__nav,\n  .layout-side-left > .brandy-tabs__nav {\n    position: relative;\n    z-index: 1;\n  }\n\n  /*\n   * Pass the root's tracks down to the regions.\n   *\n   * Three wrappers stand between the root and a region — `__panels`, the\n   * `__panel` that carries role=\"tabpanel\", and the tab block's own\n   * `.brandy-tab-panel` — so each re-declares subgrid and spans the whole grid.\n   * The regions are the tabpanel's descendants throughout, which is the point:\n   * a tab's content stays inside its single tabpanel however it is placed.\n   *\n   * Keying the panel's `display` on `.is-active` is load-bearing, and it is\n   * deliberately not `:not([hidden])` as it once was. Either selector picks out\n   * the one open panel — view.js sets the class and the attribute together — but\n   * only the class survives the cross-fade: an outgoing panel is given `hidden`\n   * the instant it is deselected, while its `display` is still transitioning\n   * away, so a `[hidden]` test would yank the grid out from under it mid-fade.\n   * Without some such guard every inactive panel would paint at once, stacked\n   * on the active one, since an author `display` rule outranks the UA's\n   * `[hidden] { display: none }`.\n   */\n  .layout-side-right,\n  .layout-side-left {\n    > .brandy-tabs__panels,\n    > .brandy-tabs__panels > .brandy-tabs__panel.is-active,\n    > .brandy-tabs__panels > .brandy-tabs__panel > .brandy-tab-panel {\n      @include brandy-tabs-track-passthrough;\n    }\n\n    // Tracks only — see the mixin. Applies to every panel, open or not, so the\n    // one on its way out keeps its regions placed while it fades.\n    > .brandy-tabs__panels > .brandy-tabs__panel {\n      @include brandy-tabs-track-passthrough-tracks;\n    }\n  }\n\n  .layout-side-right {\n    @include brandy-tabs-region-placement( 1, 2 );\n  }\n\n  .layout-side-left {\n    @include brandy-tabs-region-placement( 2, 1 );\n  }\n\n  /*\n   * A vertical nav inside a side layout.\n   *\n   * `tabPosition` does not move the nav here — the grid pins it to the first\n   * row of the main column whichever side is picked — so the sidebar styling\n   * that position drags along is wrong twice over. The nav is sized for a\n   * narrow sidebar (`--trigger-width`), which leaves a void beside it in a\n   * half-width column; and it carries a divider border meant to separate that\n   * sidebar from content, which here runs straight down the middle of the\n   * layout. With `position: right` that same border lands on the layout's\n   * outer edge and goes unnoticed, which is why only `left` looked broken.\n   *\n   * So the nav is styled as what it actually is in this layout: a stacked list\n   * heading its column. Full column width, no divider, and the active marker\n   * moved to the inline start where it reads as a list bullet instead of a\n   * stray rule.\n   */\n  /* The `.brandy-tabs` prefix is load-bearing: the position styling being\n     overridden here is written as `.brandy-tabs.tab-position-left…`, so without\n     it these rules are a class short and silently lose the cascade. Matching\n     that weight leaves a tie, which source order settles in favour of this\n     block — it is the later of the two in this file. */\n  .brandy-tabs.layout-side-right.tab-orientation-vertical,\n  .brandy-tabs.layout-side-left.tab-orientation-vertical {\n    > .brandy-tabs__nav {\n      width: auto;\n      /* The grid column already sizes the nav. Leaving the vertical rule's\n         `min-width: max-content` in place would let a long label push the\n         column wider than its track and overflow the layout. */\n      min-width: 0;\n      border-inline: 0;\n    }\n\n    .brandy-tabs__tab {\n      padding-inline: 12px 0;\n\n      &::after {\n        inset: 0 auto 0 0;\n        width: 2px;\n        height: auto;\n      }\n    }\n  }\n\n  /* `underline-below` is the one style whose whole point is that the marker\n     stays under the label wherever the nav goes, so the inline-start bar above\n     must not claim it. The extra class outweighs that rule; the values are the\n     style's own, restated because there is no way to opt a descendant out. */\n  .brandy-tabs.layout-side-right.tab-orientation-vertical.is-style-underline-below,\n  .brandy-tabs.layout-side-left.tab-orientation-vertical.is-style-underline-below {\n    .brandy-tabs__tab::after {\n      inset: auto 0 0;\n      width: auto;\n      height: 2px;\n    }\n  }\n\n  /* One column on small screens: nav, then the regions in source order. Undoing\n     the subgrid chain is enough — the regions revert to ordinary block flow. */\n  @media (max-width: 781px) {\n    .brandy-tabs.layout-side-right,\n    .brandy-tabs.layout-side-left {\n      display: flex;\n      flex-direction: column;\n      /* The grid rule above sets `align-items: start` so a short region does not\n         stretch to the height of a tall neighbour. Carried into a column flex\n         container that becomes cross-axis alignment, and every region collapses\n         to the width of its own text. */\n      align-items: stretch;\n    }\n\n    .layout-side-right,\n    .layout-side-left {\n      /* `__panels` stays a grid, with the subgrid swapped for a single plain\n         cell. Only the pass-through is being undone here, not the stacking:\n         panels sharing one cell is what lets an outgoing panel cross-fade in\n         place instead of shunting the incoming one down the page. */\n      > .brandy-tabs__panels {\n        grid-template-columns: minmax(0, 1fr);\n        grid-template-rows: auto;\n      }\n\n      > .brandy-tabs__panels > .brandy-tabs__panel {\n        grid-template-columns: none;\n        grid-template-rows: none;\n        grid-area: 1 / 1;\n      }\n\n      > .brandy-tabs__panels > .brandy-tabs__panel.is-active {\n        display: block;\n      }\n\n      > .brandy-tabs__panels > .brandy-tab-panel,\n      > .brandy-tabs__panels > .brandy-tabs__panel > .brandy-tab-panel {\n        display: block;\n        grid-area: auto;\n      }\n\n      .brandy-tabs__region {\n        grid-area: auto;\n      }\n    }\n  }\n}\n\n/* ---------------------------------------------------------------------------\n   Block spacing inside a region.\n\n   Core only writes blockGap through the layout support, which a region does\n   not declare — its placement is the parent grid's business, and core's layout\n   CSS would fight it. TabRegion/styles.js writes the value instead, and adds\n   this class alongside it.\n\n   Opt-in rather than a default, because a region is otherwise a plain block\n   container whose children space themselves with their own margins: making\n   every one a gapped column would re-space tabs nobody has touched. Those\n   margins are cleared once the class is on, so a region set to 20px measures\n   20px rather than 20px plus whatever its first block brought with it.\n--------------------------------------------------------------------------- */\n\n.brandy-tabs__region.has-block-gap {\n  display: flex;\n  flex-direction: column;\n  gap: var(--brandy-tabs-region-gap);\n\n  > * {\n    margin-block: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n   Content transitions.\n\n   Switching a tab is a `display` flip: view.js toggles `is-active` and\n   `hidden`, and the rules above turn that into `none` <-> `block`/`grid`. Two\n   things follow, and between them they are the whole feature.\n\n   An element that has just gone from `display: none` to displayed has no\n   previous style to transition from, so entrances need `@starting-style` to\n   say where they begin. Nothing needs to say *when* to run — being newly\n   rendered is the trigger, which is why this costs no JavaScript and view.js\n   is untouched.\n\n   Exits are the other half. `transition-behavior: allow-discrete` holds the\n   outgoing panel's `display` at its old value for the length of the transition\n   and only then flips it to `none`, so the panel keeps its box while it fades\n   over the panel replacing it. `hidden` still lands on it immediately, so\n   assistive technology sees the swap the moment it happens and only the paint\n   lags behind.\n\n   Browsers without `@starting-style` / `allow-discrete` drop these\n   declarations and the block keeps its original instant swap. Same outcome\n   under reduced motion, which is why the whole section sits inside\n   `no-preference` rather than undoing itself in a `reduce` block.\n\n   Per-region control needs no markup of its own: `brandy/tab-region` is a\n   static block whose save output render.php cannot reach into, but custom\n   properties inherit, so the root's `anim-*` classes reach the regions by\n   themselves. That also keeps the settings on the Tabs block, where they\n   survive a preset switch — applyLayoutPreset() rebuilds region blocks from\n   scratch, so anything stored on a region would be lost every time the layout\n   changed.\n   --------------------------------------------------------------------------- */\n\n/* Where each entrance starts — and, played the other way, where the exit ends.\n   All of them start transparent, so the map only has to carry the transform. */\n$tabs-entrances: (\n  \"fade\": none,\n  \"fade-up\": translateY(24px),\n  \"slide\": translateX(var(--anim-slide-x, 32px)),\n  \"zoom\": scale(0.94),\n);\n\n@media (prefers-reduced-motion: no-preference) {\n  .wp-block-brandy-tabs {\n    /* The switch runs in two phases rather than as a cross-fade: the old panel\n       leaves, and only once it has gone does the new one arrive. Two durations,\n       and the entrance waits out the exit. */\n    --tabs-anim-out: 400ms;\n    --tabs-anim-in: 650ms;\n    /* Mirrored curves, and the pairing matters more than the durations. The\n       entrance eases out — quick off the mark, settling gently into place. An\n       exit on that same curve is gone inside its first third and then spends\n       the rest of its time invisible, which reads as a stutter rather than a\n       departure; easing in instead holds the content legible and lets it\n       accelerate away. */\n    --tabs-anim-in-easing: cubic-bezier(0.2, 0, 0, 1);\n    --tabs-anim-out-easing: cubic-bezier(0.5, 0, 0.9, 0.3);\n    /* How far the trailing region lags the leading one. One token rather than\n       a delay control per region: the pairing that reads well is always \"one\n       then the other\", and which is which the preset already knows. */\n    --tabs-anim-stagger: 160ms;\n  }\n\n  @each $key, $from in $tabs-entrances {\n    .anim-content-#{$key} {\n      --content-from-opacity: 0;\n      --content-from: #{$from};\n    }\n\n    .anim-main-#{$key} {\n      --main-from-opacity: 0;\n      --main-from: #{$from};\n    }\n\n    .anim-side-#{$key} {\n      --side-from-opacity: 0;\n      --side-from: #{$from};\n    }\n  }\n\n  /* Stacking, for `classic` only.\n     Both panels need to be in the same place, which under the side presets is\n     already true — the pass-through puts every panel at\n     `1 / 1 / -1 / -1` — and saying it again here would be worse than\n     redundant: these selectors carry a class more than the pass-through's, so\n     a plain single-column grid would win and flatten the regions out of their\n     columns. Classic has no such grid, so it gets one. */\n  .brandy-tabs.has-tab-animation.layout-classic {\n    > .brandy-tabs__panels {\n      display: grid;\n      grid-template-columns: minmax(0, 1fr);\n    }\n\n    > .brandy-tabs__panels > .brandy-tabs__panel {\n      grid-area: 1 / 1;\n    }\n  }\n\n  /* The two phases.\n     A transition takes its delay and duration from the state it is heading\n     *to*, which is what lets one rule describe both halves: the panel losing\n     `is-active` reads the base values and leaves at once, while the one gaining\n     it reads the `is-active` values and waits out the exit before arriving. */\n  .brandy-tabs.has-tab-animation {\n    > .brandy-tabs__panels > .brandy-tabs__panel {\n      opacity: 0;\n      transition-property: opacity, display;\n      transition-duration: var(--tabs-anim-out);\n      transition-timing-function: var(--tabs-anim-out-easing);\n      transition-behavior: allow-discrete;\n\n      &.is-active {\n        opacity: 1;\n        transition-duration: var(--tabs-anim-in);\n        transition-timing-function: var(--tabs-anim-in-easing);\n        transition-delay: var(--tabs-anim-out);\n      }\n    }\n  }\n\n  /* Holding the incoming panel at nothing until its delay elapses is what\n     separates the phases, and it needs `@starting-style` to have somewhere to\n     come from — without it the panel is simply rendered at full opacity and no\n     transition runs at all, which is what made the earlier version a\n     cross-fade. Note `display` is deliberately not held back with it: the panel\n     takes up its space from the start, so the block keeps one height through\n     the switch instead of collapsing in the hand-over frame. */\n  @starting-style {\n    .brandy-tabs.has-tab-animation\n      > .brandy-tabs__panels\n      > .brandy-tabs__panel.is-active {\n      opacity: 0;\n    }\n  }\n\n  /* Entrances. Every default resolves to the resting state, so a target with\n     no `anim-` class transitions from where it already is — no animation. */\n  .brandy-tabs.layout-classic .brandy-tab-panel,\n  .brandy-tabs .brandy-tabs__region {\n    transition-property: opacity, transform;\n    transition-duration: var(--tabs-anim-in);\n    transition-timing-function: var(--tabs-anim-in-easing);\n    /* Every entrance sits behind the exit; a region's stagger is added on top\n       of it rather than replacing it. */\n    transition-delay: var(--tabs-anim-out);\n  }\n\n  .brandy-tabs__region[data-area=\"main\"] {\n    transition-delay: calc(var(--tabs-anim-out) + var(--main-delay, 0ms));\n  }\n\n  .brandy-tabs__region[data-area=\"side\"] {\n    transition-delay: calc(var(--tabs-anim-out) + var(--side-delay, 0ms));\n  }\n\n  @starting-style {\n    .brandy-tabs.layout-classic .brandy-tab-panel {\n      opacity: var(--content-from-opacity, 1);\n      transform: var(--content-from, none);\n    }\n\n    .brandy-tabs__region[data-area=\"main\"] {\n      opacity: var(--main-from-opacity, 1);\n      transform: var(--main-from, none);\n    }\n\n    .brandy-tabs__region[data-area=\"side\"] {\n      opacity: var(--side-from-opacity, 1);\n      transform: var(--side-from, none);\n    }\n  }\n\n  /* The exit, played backwards from the entrance.\n     The outgoing content returns to the very state the entrance starts from —\n     the same `--*-from` values, so \"fade up\" leaves by sinking back down and\n     \"slide in\" retreats the way it came. Nothing new has to be defined for it.\n\n     This works because `allow-discrete` keeps the outgoing panel rendered\n     while it leaves: its children are still in the tree, so a change to their\n     computed style transitions normally. The entrance cannot lean on that —\n     an arriving panel is newly rendered, which is what `@starting-style`\n     below is for.\n\n     Scoped inside `.brandy-tabs__panel` on purpose. The editor has no such\n     wrapper, so none of this reaches the canvas — where it would be actively\n     wrong, pinning every inactive tab's content at `opacity: 0` with no\n     switch to bring it back. */\n  .brandy-tabs.has-tab-animation\n    > .brandy-tabs__panels\n    > .brandy-tabs__panel:not(.is-active) {\n    /* Leaves at once — the entrance is what waits, not the exit. */\n    .brandy-tab-panel,\n    .brandy-tabs__region {\n      transition-duration: var(--tabs-anim-out);\n      transition-timing-function: var(--tabs-anim-out-easing);\n      transition-delay: 0s;\n    }\n\n    .brandy-tabs__region[data-area=\"main\"] {\n      opacity: var(--main-from-opacity, 1);\n      transform: var(--main-from, none);\n    }\n\n    .brandy-tabs__region[data-area=\"side\"] {\n      opacity: var(--side-from-opacity, 1);\n      transform: var(--side-from, none);\n    }\n  }\n\n  .brandy-tabs.has-tab-animation.layout-classic\n    > .brandy-tabs__panels\n    > .brandy-tabs__panel:not(.is-active)\n    > .brandy-tab-panel {\n    opacity: var(--content-from-opacity, 1);\n    transform: var(--content-from, none);\n  }\n\n  /* Reading order settles both the stagger and which way \"Slide in\" comes\n     from: the region in the leading column arrives first, sliding in from the\n     outer edge, and the trailing one follows. Taken from the preset so\n     flipping side-left <-> side-right stays right without touching a control. */\n  .layout-side-right {\n    .brandy-tabs__region[data-area=\"main\"] {\n      --anim-slide-x: -32px;\n    }\n\n    .brandy-tabs__region[data-area=\"side\"] {\n      --side-delay: var(--tabs-anim-stagger);\n    }\n  }\n\n  .layout-side-left {\n    .brandy-tabs__region[data-area=\"side\"] {\n      --anim-slide-x: -32px;\n    }\n\n    .brandy-tabs__region[data-area=\"main\"] {\n      --main-delay: var(--tabs-anim-stagger);\n    }\n  }\n}\n","/**\n * Shared pieces of the Tabs layout presets.\n *\n * The editor and the frontend nest the panels differently, so each stylesheet\n * has to name its own selectors — but the declarations behind them live here so\n * the two cannot drift:\n *\n *   frontend  __panels > __panel[role=tabpanel] > .brandy-tab-panel > region\n *   editor    __panels > .brandy-tab-panel                          > region\n *\n * The editor has no tabpanel wrapper: `brandy/tab`'s Edit renders straight into\n * `__panels`, and inactive tabs are hidden by editor.scss rather than by the\n * `hidden` attribute.\n */\n\n/**\n * Re-expose the root grid's tracks to a nested wrapper.\n *\n * Every level between `.brandy-tabs` and a region has to do this, otherwise the\n * region is placed against whatever the nearest grid happens to be — or, if no\n * ancestor is a grid at all, its `grid-area` is simply ignored and the layout\n * silently falls back to block flow.\n *\n * Gutters are inherited from the parent grid by default; restating them at each\n * level would multiply the gap down the chain.\n */\n@mixin brandy-tabs-track-passthrough {\n  @include brandy-tabs-track-passthrough-tracks;\n  display: grid;\n}\n\n/**\n * The track half of the pass-through, without turning the element on.\n *\n * Split out for the panels, whose `display` is now transitioned: the outgoing\n * panel is still painted while it cross-fades, so it has to keep its subgrid\n * for those few hundred milliseconds or its regions lose their placement and\n * scramble on the way out. `display` is the only part of the pass-through that\n * may be keyed on the active panel; the tracks are inert on a `display: none`\n * element, so they can safely apply to all of them.\n */\n@mixin brandy-tabs-track-passthrough-tracks {\n  grid-area: 1 / 1 / -1 / -1;\n  grid-template-columns: subgrid;\n  grid-template-rows: subgrid;\n}\n\n/**\n * Where each region sits, given a grid whose first row is the nav's band.\n *\n * Placed with grid-row/grid-column rather than the four-value `grid-area`\n * shorthand, whose order is row/col/row-end/col-end. Written as\n * `1 / 1 / -1 / -1` the side region reads as \"span every column\" and silently\n * covers the main one; naming the axes makes the single-column span explicit.\n *\n * @param {number} $main-column Column the nav and main content share.\n * @param {number} $side-column Column the side area spans.\n */\n@mixin brandy-tabs-region-placement( $main-column, $side-column ) {\n  .brandy-tabs__region[data-area='main'] {\n    grid-row: 2;\n    grid-column: $main-column;\n  }\n\n  .brandy-tabs__region[data-area='side'] {\n    grid-row: 1 / -1;\n    grid-column: $side-column;\n  }\n}\n"],"names":[],"sourceRoot":""}