/* Image shapes.
 *
 * These are border-radius rather than clip-path or a mask wherever the shape
 * can be expressed as one, and that is the design: a clip or a mask cuts the
 * border away with everything else, so the ringed look these shapes are for
 * would be impossible. Core makes the same trade — is-style-rounded rounds
 * with a radius, is-style-circle-mask masks and then has to force
 * border-radius to 0.
 *
 * The border itself is left to the block's own Border controls, so an author
 * picks the shape here and the ring colour and width where they already expect
 * to find them.
 *
 * The two edge treatments are the exceptions. A repeating edge is not a
 * corner, and a concave bite is the opposite of one, so no radius can draw
 * either and both have to mask — which costs them the border ring. They are
 * kept in the same set anyway because an author looking for an edge treatment
 * looks in the Styles panel, not in a second place.
 */

/* One geometry rule for every shape; each style below only names a radius.
 *
 * It lands on the figure so a border curves with the shape, and on the image so
 * the photo is clipped to the same curve. Both are needed: core hands the
 * radius down to the image with
 * `.wp-block-image[style*=border-radius] img { border-radius: inherit }`, an
 * attribute selector against the inline style string, which a shape set from a
 * stylesheet never matches. Setting only the figure leaves a shaped ring around
 * a square photo, with nothing to explain why. */
.wp-block-image[class*="is-style-shape-"],
.wp-block-image[class*="is-style-shape-"] > a,
.wp-block-image[class*="is-style-shape-"] img,
.wp-block-post-featured-image[class*="is-style-shape-"],
.wp-block-post-featured-image[class*="is-style-shape-"] > a,
.wp-block-post-featured-image[class*="is-style-shape-"] img,
.wp-block-brandy-category-image[class*="is-style-shape-"],
.wp-block-brandy-category-image[class*="is-style-shape-"] a,
.wp-block-brandy-category-image[class*="is-style-shape-"] img {
	border-radius: var(--brandy-image-shape);
}

/* Group carries the shape on its own box only — the radius must not reach the
   blocks inside, or every image in the group would be cut to the same curve.
   Hence its own rule rather than another selector on the list above.

   The clip is what makes the shape read at all: a background colour is already
   clipped by the radius, but a child image or a nested background is not, and
   would square the corners straight back off. `clip` rather than `hidden` so
   the group does not become a scroll container, which would break a sticky
   child and swallow anything an inner block deliberately overflows.

   The corners eat into the padding box, so a shape with deep corners
   (blob, leaf, petal, drop) needs the author to raise the group's own padding
   until the content clears the curve. Nothing here can do that for them: the
   safe padding depends on the group's aspect ratio, which is only known once
   it renders. */
.wp-block-group[class*="is-style-shape-"] {
	border-radius: var(--brandy-image-shape);
	overflow: clip;
}

/* Declared on the bare class so the custom property is inherited by the anchor
   and image inside, which is what lets one rule above serve every shape. */
.is-style-shape-blob {
	--brandy-image-shape: 62% 38% 46% 54% / 60% 57% 43% 40%;
}

.is-style-shape-blob-soft {
	--brandy-image-shape: 48% 52% 41% 59% / 55% 43% 57% 45%;
}

.is-style-shape-arch {
	--brandy-image-shape: 9999px 9999px 12px 12px;
}

.is-style-shape-dome {
	--brandy-image-shape: 50% 50% 0 0;
}

/* Leaf and petal are the same shape mirrored, so they name opposite diagonals.
   Written out in full: `9999px 12px 9999px 12px` collapses to the two-value
   form, which made both styles resolve to an identical radius. */
.is-style-shape-leaf {
	--brandy-image-shape: 12px 9999px 12px 9999px;
}

.is-style-shape-petal {
	--brandy-image-shape: 9999px 12px 9999px 12px;
}

.is-style-shape-squircle {
	--brandy-image-shape: 28%;
}

/* A circle with one corner squared off, which is what gives it the drop
   silhouette. The tight corner sits bottom-left so the shape leans into text
   set beside it.
   Measured against the reference rather than guessed: the corner rounds over
   roughly a tenth of the box, so anything past ~15% loses the corner and reads
   as a plain circle again. */
.is-style-shape-drop {
	--brandy-image-shape: 50% 50% 50% 12%;
}

/* An organic bite out of the left edge, for a wide section whose background
   should not meet the one beside it in a straight line.

   The curve is concave — it caves into the section rather than bulging out of
   it — and that is why this masks instead of using a radius. border-radius
   only ever cuts a corner convex; asking it for this shape gives a large
   rounded corner curving the opposite way, which is a different design, not a
   near miss.

   One ellipse centred on the left edge does the whole thing: transparent
   inside is the bite, opaque outside covers the rest of the box, so the
   gradient's unbounded outer colour fills the section however wide it gets.
   Centring at 55% rather than 50% drops the widest point just below the
   midline, which is what keeps it reading as organic instead of as a lens.

   The horizontal radius is px and the vertical is %, deliberately. Every other
   shape here is a silhouette that should scale with its box, but this is an
   edge treatment on a section that may be 400px or 1600px wide: in % the bite
   would be shallow on a phone and enormous on a desktop, while the vertical
   radius does need to track the section's height so the bite always runs the
   full edge. */
.is-style-shape-blob-left {
	/* No corner is rounded here, but the shared geometry rule above still
	   matches this class, so the property has to resolve to something. */
	--brandy-image-shape: 0;

	--brandy-blob-left-mask:
		radial-gradient(70px 55% at 0 55%, transparent 99%, #000 100%);

	-webkit-mask: var(--brandy-blob-left-mask);
	mask: var(--brandy-blob-left-mask);
}

/* Same reasoning as the scallop floor below: on an image the bite is cut from
   the photo, but a group's content would sit in the removed wedge. */
.wp-block-group.is-style-shape-blob-left {
	padding-left: 70px;
}

/* Scalloped edges — a row of bumps along one edge, two, or all four.

   Two mask layers per edge, unioned (the shorthand's default composite is
   add): a row of bumps in the edge band and a rectangle covering everything
   inside it. Each bump is the outer half of an ellipse of rx = size/2 and
   ry = depth: `ellipse closest-side` in a tile `size` wide, centred `depth` in
   from the edge, makes exactly those radii, so neighbouring bumps come out
   tangent at the flat line rather than gapped or overlapping. The 98% stop is
   a feather — a hard stop at 100% leaves the arcs visibly jagged.

   Two knobs, read with fallbacks and never declared on the element, so a
   pattern (or the Site Editor's custom CSS) can set them on the block or any
   ancestor and win regardless of stylesheet order:
     --brandy-scallop-size   bump size along the edge (the tile pitch), 56px
     --brandy-scallop-depth  how far the bumps stand out; half the size makes
                             a semicircle, less makes a shallower cap
   Both are px, not %: the tile has to keep a fixed pitch for the bumps to keep
   their shape, and an edge treatment on a section that may be 400px or 1600px
   wide wants the same bump at every width. Tiles are centred on the edge, so
   a width that is not a multiple of the size cuts both end bumps equally. */
[class*="is-style-shape-scallop"] {
	/* No corner is rounded here, but the shared geometry rule above still
	   matches this class, so the property has to resolve to something. */
	--brandy-image-shape: 0;

	--_scallop-size: var(--brandy-scallop-size, 56px);
	--_scallop-depth: var(--brandy-scallop-depth, calc(var(--_scallop-size) / 2));

	/* The four bump rows and the flat core; each style below picks its layers. */
	--_scallop-top: radial-gradient(ellipse closest-side at 50% var(--_scallop-depth), #000 98%, transparent) 50% 0 / var(--_scallop-size) 100% repeat-x;
	--_scallop-bottom: radial-gradient(ellipse closest-side at 50% calc(100% - var(--_scallop-depth)), #000 98%, transparent) 50% 100% / var(--_scallop-size) 100% repeat-x;
	--_scallop-left: radial-gradient(ellipse closest-side at var(--_scallop-depth) 50%, #000 98%, transparent) 0 50% / 100% var(--_scallop-size) repeat-y;
	--_scallop-right: radial-gradient(ellipse closest-side at calc(100% - var(--_scallop-depth)) 50%, #000 98%, transparent) 100% 50% / 100% var(--_scallop-size) repeat-y;
	--_scallop-core: linear-gradient(#000, #000);

	-webkit-mask: var(--brandy-scallop-mask);
	mask: var(--brandy-scallop-mask);
}

.is-style-shape-scallop-top {
	--brandy-scallop-mask:
		var(--_scallop-top),
		var(--_scallop-core) 0 100% / 100% calc(100% - var(--_scallop-depth)) no-repeat;
}

.is-style-shape-scallop-bottom {
	--brandy-scallop-mask:
		var(--_scallop-bottom),
		var(--_scallop-core) 0 0 / 100% calc(100% - var(--_scallop-depth)) no-repeat;
}

.is-style-shape-scallop-top-bottom {
	--brandy-scallop-mask:
		var(--_scallop-top),
		var(--_scallop-bottom),
		var(--_scallop-core) 0 var(--_scallop-depth) / 100% calc(100% - var(--_scallop-depth) * 2) no-repeat;
}

.is-style-shape-scallop-left {
	--brandy-scallop-mask:
		var(--_scallop-left),
		var(--_scallop-core) 100% 0 / calc(100% - var(--_scallop-depth)) 100% no-repeat;
}

.is-style-shape-scallop-right {
	--brandy-scallop-mask:
		var(--_scallop-right),
		var(--_scallop-core) 0 0 / calc(100% - var(--_scallop-depth)) 100% no-repeat;
}

/* All four edges. The bump rows overlap at the corners and the union simply
   adds, which is what a scalloped corner looks like on the reference. */
.is-style-shape-scallop-all {
	--brandy-scallop-mask:
		var(--_scallop-top),
		var(--_scallop-bottom),
		var(--_scallop-left),
		var(--_scallop-right),
		var(--_scallop-core) var(--_scallop-depth) var(--_scallop-depth) / calc(100% - var(--_scallop-depth) * 2) calc(100% - var(--_scallop-depth) * 2) no-repeat;
}

/* On an image the bumps are cut from the photo itself, so nothing has to move.
   A group paints its own background behind content, and the edge band of that
   background is where the valleys are cut away — so content needs to start
   inside the bump line or the first line of text sits in a gap. These are
   floors only: the block's own padding control writes an inline style and
   wins, which is the right way round, since most sections want far more room
   than this. */
.wp-block-group.is-style-shape-scallop-top,
.wp-block-group.is-style-shape-scallop-top-bottom,
.wp-block-group.is-style-shape-scallop-all {
	padding-top: var(--_scallop-depth);
}

.wp-block-group.is-style-shape-scallop-bottom,
.wp-block-group.is-style-shape-scallop-top-bottom,
.wp-block-group.is-style-shape-scallop-all {
	padding-bottom: var(--_scallop-depth);
}

.wp-block-group.is-style-shape-scallop-left,
.wp-block-group.is-style-shape-scallop-all {
	padding-left: var(--_scallop-depth);
}

.wp-block-group.is-style-shape-scallop-right,
.wp-block-group.is-style-shape-scallop-all {
	padding-right: var(--_scallop-depth);
}
