css-is-awesome 1.19.2 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +11 -5
- package/CHANGELOG.md +20 -0
- package/CONTRACT.md +10 -0
- package/MIGRATION.md +58 -0
- package/README.md +19 -11
- package/bin/analyze.cjs +47 -2
- package/bin/cia.cjs +10 -0
- package/bin/fix-theme.cjs +151 -0
- package/llm.txt +5 -5
- package/mcp/server.cjs +64 -3
- package/package.json +6 -3
- package/public/theme.css +138 -0
- package/public/themes/boilerplate/theme.css +6 -0
- package/public/themes/boilerplate-dark/theme.css +6 -0
- package/public/themes/boilerplate-light/theme.css +6 -0
- package/public/themes/cupertino/theme.css +6 -0
- package/public/themes/cupertino-dark/theme.css +6 -0
- package/public/themes/cupertino-light/theme.css +6 -0
- package/public/themes/glass/theme.css +6 -0
- package/public/themes/glass-dark/theme.css +6 -0
- package/public/themes/glass-light/theme.css +6 -0
- package/public/themes/graphite/theme.css +6 -0
- package/public/themes/graphite-dark/theme.css +6 -0
- package/public/themes/graphite-light/theme.css +6 -0
- package/public/themes/press/theme.css +6 -0
- package/public/themes/press-dark/theme.css +6 -0
- package/public/themes/press-light/theme.css +6 -0
- package/public/themes/prism/theme.css +6 -0
- package/public/themes/prism-dark/theme.css +6 -0
- package/public/themes/prism-light/theme.css +6 -0
- package/public/themes/sketchbook/theme.css +6 -0
- package/public/themes/sketchbook-dark/theme.css +6 -0
- package/public/themes/sketchbook-light/theme.css +6 -0
- package/public/themes/terminal/theme.css +6 -0
- package/public/themes/terminal-dark/theme.css +6 -0
- package/public/themes/terminal-light/theme.css +6 -0
- package/scripts/audit-pairs.json +171 -23
- package/scripts/fix-theme.cjs +184 -0
- package/scripts/theme-contract.json +33 -4
- package/scripts/theme-validator.js +40 -1
- package/scss/_layout.scss +129 -0
package/scss/_layout.scss
CHANGED
|
@@ -595,3 +595,132 @@ $_flow: (
|
|
|
595
595
|
margin-inline-start: auto;
|
|
596
596
|
}
|
|
597
597
|
}
|
|
598
|
+
|
|
599
|
+
// ============================================================================
|
|
600
|
+
// PAGE SURFACES — hero + band
|
|
601
|
+
// ============================================================================
|
|
602
|
+
// Two page-level backgrounds a theme can own outright: `hero` for a landing
|
|
603
|
+
// page, `band` for a section stripe or a footer. Each slot carries four
|
|
604
|
+
// optional tokens — background colour, image, ink, scrim.
|
|
605
|
+
//
|
|
606
|
+
// NOTHING HERE RUNS UNTIL YOU ASK FOR IT. cia never applies a page surface
|
|
607
|
+
// automatically: not on `body`, not from a layout mixin, not from the reset.
|
|
608
|
+
// That guarantee is why adding these tokens to every shipped theme cannot
|
|
609
|
+
// change an existing consumer's page, and `tests/no-auto-surface.test.mjs`
|
|
610
|
+
// asserts it against the compiled bundles so it cannot be broken by accident.
|
|
611
|
+
//
|
|
612
|
+
// Every token falls back, so a theme that declares none of them still renders:
|
|
613
|
+
// background → the deprecated --background-hero, then the page surface
|
|
614
|
+
// ink → --text-primary
|
|
615
|
+
// image → none (and with no image, no scrim is drawn)
|
|
616
|
+
//
|
|
617
|
+
// The scrim is layered as a gradient in the SAME background-image as the
|
|
618
|
+
// image rather than as a pseudo-element or an extra wrapper, so `surface`
|
|
619
|
+
// works identically on <body> and on a <section>, and stacking context,
|
|
620
|
+
// overflow and child positioning are left alone.
|
|
621
|
+
|
|
622
|
+
$_surface-slots: (hero, band) !default;
|
|
623
|
+
|
|
624
|
+
@mixin surface($slot: hero, $image: null, $scrim: null) {
|
|
625
|
+
@if not list.index($_surface-slots, $slot) {
|
|
626
|
+
@error "surface(): unknown slot '#{$slot}'. Expected one of: hero, band.";
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
$bg: var(--page-#{$slot}-bg, var(--background-#{$slot}, var(--surface-default, var(--paper))));
|
|
630
|
+
$ink: var(--page-#{$slot}-ink, var(--text-primary, var(--ink)));
|
|
631
|
+
|
|
632
|
+
// The scrim only paints when there is an image UNDER it. Defaulting it to a
|
|
633
|
+
// colour would put a 50% black wash over every colour-only hero — which is
|
|
634
|
+
// both wrong and a silent visual change for anyone who sets just a colour.
|
|
635
|
+
//
|
|
636
|
+
// $image given → the caller has an image, so the scrim defaults to the
|
|
637
|
+
// 50% black that keeps text legible over a photo.
|
|
638
|
+
// $image omitted → the image comes from the token (or is absent), so the
|
|
639
|
+
// scrim defaults to `transparent` and the token carries
|
|
640
|
+
// the value. The theme editor writes a scrim whenever it
|
|
641
|
+
// writes an image, so the safe default still arrives.
|
|
642
|
+
$img: var(--page-#{$slot}-image, none);
|
|
643
|
+
$scrim-default: transparent;
|
|
644
|
+
@if $image {
|
|
645
|
+
$img: $image;
|
|
646
|
+
$scrim-default: rgb(0 0 0 / 0.5);
|
|
647
|
+
}
|
|
648
|
+
$scrim-color: var(--page-#{$slot}-scrim, #{$scrim-default});
|
|
649
|
+
@if $scrim {
|
|
650
|
+
$scrim-color: $scrim;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
background-color: #{$bg};
|
|
654
|
+
background-image: linear-gradient(#{$scrim-color}, #{$scrim-color}), #{$img};
|
|
655
|
+
background-size: cover;
|
|
656
|
+
background-position: center;
|
|
657
|
+
background-repeat: no-repeat;
|
|
658
|
+
color: #{$ink};
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// The attribute form of the same thing, for consumers with no Sass build.
|
|
662
|
+
// Emitted only when this mixin is called — it is not part of the reset.
|
|
663
|
+
@mixin surface-attributes {
|
|
664
|
+
@each $slot in $_surface-slots {
|
|
665
|
+
[data-surface='#{$slot}'] {
|
|
666
|
+
@include surface($slot);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// ----------------------------------------------------------------------------
|
|
672
|
+
// WAVE DIVIDER — a curved edge between two sections, pure CSS
|
|
673
|
+
// ----------------------------------------------------------------------------
|
|
674
|
+
// Draws the curve with a radial-gradient mask on a ::before/::after, so there
|
|
675
|
+
// is no SVG file to host and the shape inherits whatever colour you give it.
|
|
676
|
+
// `$direction: down` curves the edge INTO the element (a valley at the top);
|
|
677
|
+
// `up` bulges it outward. `$flip: true` puts the wave on the bottom edge.
|
|
678
|
+
//
|
|
679
|
+
// .hero { @include cia.surface(hero); @include cia.wave-divider($height: 4rem); }
|
|
680
|
+
//
|
|
681
|
+
// The wave paints in `$color`, which defaults to the NEXT section's surface so
|
|
682
|
+
// the curve reads as that section rising into this one.
|
|
683
|
+
@mixin wave-divider(
|
|
684
|
+
$height: 3rem,
|
|
685
|
+
$color: var(--surface-default, var(--paper)),
|
|
686
|
+
$direction: down,
|
|
687
|
+
$flip: false,
|
|
688
|
+
$position: after
|
|
689
|
+
) {
|
|
690
|
+
@if $direction != down and $direction != up {
|
|
691
|
+
@error "wave-divider(): $direction must be `down` or `up`, got `#{$direction}`.";
|
|
692
|
+
}
|
|
693
|
+
@if $position != after and $position != before {
|
|
694
|
+
@error "wave-divider(): $position must be `after` or `before`, got `#{$position}`.";
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
position: relative;
|
|
698
|
+
isolation: isolate;
|
|
699
|
+
|
|
700
|
+
&::#{$position} {
|
|
701
|
+
content: '';
|
|
702
|
+
position: absolute;
|
|
703
|
+
inset-inline: 0;
|
|
704
|
+
block-size: $height;
|
|
705
|
+
pointer-events: none;
|
|
706
|
+
z-index: 1;
|
|
707
|
+
|
|
708
|
+
@if $flip {
|
|
709
|
+
inset-block-start: calc(100% - #{$height});
|
|
710
|
+
} @else {
|
|
711
|
+
inset-block-end: calc(100% - #{$height});
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
// An ellipse wider than the box gives a shallow, natural curve rather
|
|
715
|
+
// than the circular arc a border-radius would produce.
|
|
716
|
+
@if $direction == down {
|
|
717
|
+
background: #{$color};
|
|
718
|
+
// stylelint-disable-next-line function-no-unknown
|
|
719
|
+
mask: radial-gradient(120% #{$height} at 50% 0%, transparent 99%, #000 100%);
|
|
720
|
+
} @else {
|
|
721
|
+
background: #{$color};
|
|
722
|
+
// stylelint-disable-next-line function-no-unknown
|
|
723
|
+
mask: radial-gradient(120% #{$height} at 50% 100%, #000 99%, transparent 100%);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
}
|