diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..c0d283b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,59 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Mizu (水) is a FileMaker theme and add-on by Proof+Geist, inspired by Material Design and IBM Carbon. It targets FileMaker 19+ and ships as a `.fmaddon` archive with a companion `.fmp12` helper file. + +## Build Process + +The build is a hybrid manual/scripted process — theme changes happen inside FileMaker, then XML is cleaned up and packaged: + +1. Update theme in FileMaker (foundations-dev file) +2. Update version in `mizu_theme::__versionString` and `FMAddonTemplate_Version` on `__FMdAddonTemplate_Metadata` layout +3. Export via "Generate Add-on" in FileMaker (outputs to `~/Library/Application Support/FileMaker/Extensions/AddonModules`) +4. Copy `proof_mizu_theme/` folder to project root +5. Clean up extraneous XML (see below) +6. Build the archive: `source build.sh` + +### Build Command + +``` +source build.sh +``` + +Requires `xar` utility. Creates `proof_mizu_theme.fmaddon` from the `proof_mizu_theme/` directory. + +### XML Cleanup After Export + +FileMaker generates duplicate objects that must be manually removed. Use VSCode compare against `previous/` versions to detect diffs. Key fixes: + +- **Portals layout**: Remove 2 extra buttons in Portal UUID `47F1ED16-...`, set membercount to 5 +- **Tabs layout**: Remove 3 duplicate button bar buttons in SlidePanel UUID `B2C37ECE-...`, set membercount to 14 +- **List layout**: Remove 2 extra objects in Portal, set membercount to 3 + +See `build-how-to.md` for exact XPaths and UUIDs. + +### Testing + +1. Uninstall existing mizu add-on in FileMaker +2. Delete `.fmaddon` file and `proof_mizu_theme/` from FileMaker's `Extensions/AddonModules` directory +3. Double-click the new `.fmaddon` to install +4. Create a new FileMaker file, add the add-on, verify no duplicate buttons on Portal/List/Tabs layouts + +## Architecture + +This is an XML/JSON-based theme definition, not a traditional code project. + +### Key Files + +- **`proof_mizu_theme/template.xml`** — Main theme definition (~7,000 lines). Contains structure definitions (FieldCatalog, LayoutCatalog with 13 layouts) and literal content in CDATA sections. **Do not modify CDATA sections** — it breaks XML folding and risks corrupting the file. +- **`proof_mizu_theme/info.json`** — Core metadata (GUID, version, supported clients) +- **`proof_mizu_theme/info_[lang].json`** + **`[lang].xml`** + **`records_[lang].xml`** — Localized strings for 11 languages (en, de, es, fr, it, ja, ko, nl, pt, sv, zh) +- **`proof_mizu_helper.fmp12`** — Companion helper file (binary, Git LFS tracked) +- **`previous/`** — Previous template.xml versions kept for diff comparison during builds + +### Binary Files + +`.fmp12`, `.fmaddon`, and `.zip` files are tracked via Git LFS (configured in `.gitattributes`). diff --git a/build-shadcn.sh b/build-shadcn.sh new file mode 100755 index 0000000..e035b85 --- /dev/null +++ b/build-shadcn.sh @@ -0,0 +1,9 @@ +#! /bin/bash +if xar -h &> /dev/null +then + echo "xar could not be found" +else + + xar -cf proof_shadcn_theme.fmaddon proof_shadcn_theme/ + echo 'build succesful' +fi diff --git a/proof_shadcn_theme.fmaddon b/proof_shadcn_theme.fmaddon new file mode 100644 index 0000000..c8e21db --- /dev/null +++ b/proof_shadcn_theme.fmaddon @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ffb73b472c5cbcc096e6acb063ea28e972e0a5936e6c1b8cd65353a88f8bc77 +size 693596 diff --git a/proof_shadcn_theme/de.xml b/proof_shadcn_theme/de.xml new file mode 100644 index 0000000..ef70b08 --- /dev/null +++ b/proof_shadcn_theme/de.xml @@ -0,0 +1,98 @@ + + + com.fmi.basedirectory.CB285A0FD66A28850057FEB1F4A82D17 + Mizu/ + Mizu/ + com.fmi.basedirectory.Mizu/ + + + + com.fmi.basetable.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.basetable.__FMAddonTemplate_Metadata + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::1A6F6D8A5D201F2A21420B43C5345AE0 + __FMAddonTemplate_Version + __FMAddonTemplate_Version + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Version + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::3DF4202D460A0197901676D33510E2A9 + __FMAddonTemplate_GUID + __FMAddonTemplate_GUID + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_GUID + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::4C401D80F095E4875C589E7F30613788 + __FMAddonTemplate_PreviewImage + __FMAddonTemplate_PreviewImage + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_PreviewImage + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::58C8AA9702E724A8E8528A4EFD8E39BC + __FMAddonTemplate_Icon + __FMAddonTemplate_Icon + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Icon + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::5A65B734A19B7A9D40A8E233BCECC32B + __FMAddonTemplate_Desc + __FMAddonTemplate_Desc + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Desc + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::9C2DB678CD3FAB550FD3E0896225AC19 + __FMAddonTemplate_Clients + __FMAddonTemplate_Clients + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Clients + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::B0F082A2B4B8CD0DD4CC13D936B12D82 + __FMAddonTemplate_Attribution + __FMAddonTemplate_Attribution + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Attribution + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::BF67E2BFE93D889A4BB3ACAEF0833675 + __FMAddonTemplate_URL + __FMAddonTemplate_URL + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_URL + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::C3705CECC929CE96E6BCD1628F27214E + __FMAddonTemplate_Title + __FMAddonTemplate_Title + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Title + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::DFF29DF31A6BCD82433020A5B2096A06 + __FMAddonTemplate_Category + __FMAddonTemplate_Category + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Category + + + + com.fmi.calculation.text.E06123D571693687770B1259FAD99B28 + Proof Add-on Module + Proof Add-on Module + com.fmi.calculation.text.Proof Add-on Module + + + + com.fmi.tableoccurrence.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.tableoccurrence.__FMAddonTemplate_Metadata + diff --git a/proof_shadcn_theme/en.xml b/proof_shadcn_theme/en.xml new file mode 100644 index 0000000..ef70b08 --- /dev/null +++ b/proof_shadcn_theme/en.xml @@ -0,0 +1,98 @@ + + + com.fmi.basedirectory.CB285A0FD66A28850057FEB1F4A82D17 + Mizu/ + Mizu/ + com.fmi.basedirectory.Mizu/ + + + + com.fmi.basetable.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.basetable.__FMAddonTemplate_Metadata + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::1A6F6D8A5D201F2A21420B43C5345AE0 + __FMAddonTemplate_Version + __FMAddonTemplate_Version + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Version + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::3DF4202D460A0197901676D33510E2A9 + __FMAddonTemplate_GUID + __FMAddonTemplate_GUID + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_GUID + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::4C401D80F095E4875C589E7F30613788 + __FMAddonTemplate_PreviewImage + __FMAddonTemplate_PreviewImage + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_PreviewImage + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::58C8AA9702E724A8E8528A4EFD8E39BC + __FMAddonTemplate_Icon + __FMAddonTemplate_Icon + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Icon + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::5A65B734A19B7A9D40A8E233BCECC32B + __FMAddonTemplate_Desc + __FMAddonTemplate_Desc + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Desc + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::9C2DB678CD3FAB550FD3E0896225AC19 + __FMAddonTemplate_Clients + __FMAddonTemplate_Clients + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Clients + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::B0F082A2B4B8CD0DD4CC13D936B12D82 + __FMAddonTemplate_Attribution + __FMAddonTemplate_Attribution + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Attribution + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::BF67E2BFE93D889A4BB3ACAEF0833675 + __FMAddonTemplate_URL + __FMAddonTemplate_URL + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_URL + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::C3705CECC929CE96E6BCD1628F27214E + __FMAddonTemplate_Title + __FMAddonTemplate_Title + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Title + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::DFF29DF31A6BCD82433020A5B2096A06 + __FMAddonTemplate_Category + __FMAddonTemplate_Category + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Category + + + + com.fmi.calculation.text.E06123D571693687770B1259FAD99B28 + Proof Add-on Module + Proof Add-on Module + com.fmi.calculation.text.Proof Add-on Module + + + + com.fmi.tableoccurrence.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.tableoccurrence.__FMAddonTemplate_Metadata + diff --git a/proof_shadcn_theme/es.xml b/proof_shadcn_theme/es.xml new file mode 100644 index 0000000..ef70b08 --- /dev/null +++ b/proof_shadcn_theme/es.xml @@ -0,0 +1,98 @@ + + + com.fmi.basedirectory.CB285A0FD66A28850057FEB1F4A82D17 + Mizu/ + Mizu/ + com.fmi.basedirectory.Mizu/ + + + + com.fmi.basetable.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.basetable.__FMAddonTemplate_Metadata + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::1A6F6D8A5D201F2A21420B43C5345AE0 + __FMAddonTemplate_Version + __FMAddonTemplate_Version + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Version + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::3DF4202D460A0197901676D33510E2A9 + __FMAddonTemplate_GUID + __FMAddonTemplate_GUID + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_GUID + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::4C401D80F095E4875C589E7F30613788 + __FMAddonTemplate_PreviewImage + __FMAddonTemplate_PreviewImage + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_PreviewImage + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::58C8AA9702E724A8E8528A4EFD8E39BC + __FMAddonTemplate_Icon + __FMAddonTemplate_Icon + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Icon + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::5A65B734A19B7A9D40A8E233BCECC32B + __FMAddonTemplate_Desc + __FMAddonTemplate_Desc + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Desc + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::9C2DB678CD3FAB550FD3E0896225AC19 + __FMAddonTemplate_Clients + __FMAddonTemplate_Clients + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Clients + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::B0F082A2B4B8CD0DD4CC13D936B12D82 + __FMAddonTemplate_Attribution + __FMAddonTemplate_Attribution + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Attribution + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::BF67E2BFE93D889A4BB3ACAEF0833675 + __FMAddonTemplate_URL + __FMAddonTemplate_URL + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_URL + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::C3705CECC929CE96E6BCD1628F27214E + __FMAddonTemplate_Title + __FMAddonTemplate_Title + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Title + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::DFF29DF31A6BCD82433020A5B2096A06 + __FMAddonTemplate_Category + __FMAddonTemplate_Category + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Category + + + + com.fmi.calculation.text.E06123D571693687770B1259FAD99B28 + Proof Add-on Module + Proof Add-on Module + com.fmi.calculation.text.Proof Add-on Module + + + + com.fmi.tableoccurrence.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.tableoccurrence.__FMAddonTemplate_Metadata + diff --git a/proof_shadcn_theme/fr.xml b/proof_shadcn_theme/fr.xml new file mode 100644 index 0000000..ef70b08 --- /dev/null +++ b/proof_shadcn_theme/fr.xml @@ -0,0 +1,98 @@ + + + com.fmi.basedirectory.CB285A0FD66A28850057FEB1F4A82D17 + Mizu/ + Mizu/ + com.fmi.basedirectory.Mizu/ + + + + com.fmi.basetable.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.basetable.__FMAddonTemplate_Metadata + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::1A6F6D8A5D201F2A21420B43C5345AE0 + __FMAddonTemplate_Version + __FMAddonTemplate_Version + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Version + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::3DF4202D460A0197901676D33510E2A9 + __FMAddonTemplate_GUID + __FMAddonTemplate_GUID + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_GUID + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::4C401D80F095E4875C589E7F30613788 + __FMAddonTemplate_PreviewImage + __FMAddonTemplate_PreviewImage + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_PreviewImage + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::58C8AA9702E724A8E8528A4EFD8E39BC + __FMAddonTemplate_Icon + __FMAddonTemplate_Icon + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Icon + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::5A65B734A19B7A9D40A8E233BCECC32B + __FMAddonTemplate_Desc + __FMAddonTemplate_Desc + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Desc + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::9C2DB678CD3FAB550FD3E0896225AC19 + __FMAddonTemplate_Clients + __FMAddonTemplate_Clients + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Clients + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::B0F082A2B4B8CD0DD4CC13D936B12D82 + __FMAddonTemplate_Attribution + __FMAddonTemplate_Attribution + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Attribution + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::BF67E2BFE93D889A4BB3ACAEF0833675 + __FMAddonTemplate_URL + __FMAddonTemplate_URL + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_URL + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::C3705CECC929CE96E6BCD1628F27214E + __FMAddonTemplate_Title + __FMAddonTemplate_Title + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Title + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::DFF29DF31A6BCD82433020A5B2096A06 + __FMAddonTemplate_Category + __FMAddonTemplate_Category + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Category + + + + com.fmi.calculation.text.E06123D571693687770B1259FAD99B28 + Proof Add-on Module + Proof Add-on Module + com.fmi.calculation.text.Proof Add-on Module + + + + com.fmi.tableoccurrence.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.tableoccurrence.__FMAddonTemplate_Metadata + diff --git a/proof_shadcn_theme/icon.png b/proof_shadcn_theme/icon.png new file mode 100644 index 0000000..3820bad Binary files /dev/null and b/proof_shadcn_theme/icon.png differ diff --git a/proof_shadcn_theme/icon@2x.png b/proof_shadcn_theme/icon@2x.png new file mode 100644 index 0000000..1ad1b26 Binary files /dev/null and b/proof_shadcn_theme/icon@2x.png differ diff --git a/proof_shadcn_theme/info.json b/proof_shadcn_theme/info.json new file mode 100644 index 0000000..81c02ce --- /dev/null +++ b/proof_shadcn_theme/info.json @@ -0,0 +1,11 @@ +{ + "GUID" : "F3A896D8-5322-475C-8206-AA6C4AFD87E4", + "Clients" : + [ + "Pro","Go" + ], + "Attribution" : "Proof+Geist", + "URL" : "https://github.com/proofgeist/mizu", + "Icon_Color" : "", + "Version" : "1.0" +} diff --git a/proof_shadcn_theme/info_de.json b/proof_shadcn_theme/info_de.json new file mode 100644 index 0000000..76e1804 --- /dev/null +++ b/proof_shadcn_theme/info_de.json @@ -0,0 +1,11 @@ +{ + "Title": "shadcn by Proof+Geist", + "Description": "Adds the shadcn theme to your file", + "Category": "Themes", + "Features": [], + "Optimized": [ + "Desktop", + "Tablet", + "Mobile" + ] +} diff --git a/proof_shadcn_theme/info_en.json b/proof_shadcn_theme/info_en.json new file mode 100644 index 0000000..76e1804 --- /dev/null +++ b/proof_shadcn_theme/info_en.json @@ -0,0 +1,11 @@ +{ + "Title": "shadcn by Proof+Geist", + "Description": "Adds the shadcn theme to your file", + "Category": "Themes", + "Features": [], + "Optimized": [ + "Desktop", + "Tablet", + "Mobile" + ] +} diff --git a/proof_shadcn_theme/info_es.json b/proof_shadcn_theme/info_es.json new file mode 100644 index 0000000..76e1804 --- /dev/null +++ b/proof_shadcn_theme/info_es.json @@ -0,0 +1,11 @@ +{ + "Title": "shadcn by Proof+Geist", + "Description": "Adds the shadcn theme to your file", + "Category": "Themes", + "Features": [], + "Optimized": [ + "Desktop", + "Tablet", + "Mobile" + ] +} diff --git a/proof_shadcn_theme/info_fr.json b/proof_shadcn_theme/info_fr.json new file mode 100644 index 0000000..76e1804 --- /dev/null +++ b/proof_shadcn_theme/info_fr.json @@ -0,0 +1,11 @@ +{ + "Title": "shadcn by Proof+Geist", + "Description": "Adds the shadcn theme to your file", + "Category": "Themes", + "Features": [], + "Optimized": [ + "Desktop", + "Tablet", + "Mobile" + ] +} diff --git a/proof_shadcn_theme/info_it.json b/proof_shadcn_theme/info_it.json new file mode 100644 index 0000000..76e1804 --- /dev/null +++ b/proof_shadcn_theme/info_it.json @@ -0,0 +1,11 @@ +{ + "Title": "shadcn by Proof+Geist", + "Description": "Adds the shadcn theme to your file", + "Category": "Themes", + "Features": [], + "Optimized": [ + "Desktop", + "Tablet", + "Mobile" + ] +} diff --git a/proof_shadcn_theme/info_ja.json b/proof_shadcn_theme/info_ja.json new file mode 100644 index 0000000..76e1804 --- /dev/null +++ b/proof_shadcn_theme/info_ja.json @@ -0,0 +1,11 @@ +{ + "Title": "shadcn by Proof+Geist", + "Description": "Adds the shadcn theme to your file", + "Category": "Themes", + "Features": [], + "Optimized": [ + "Desktop", + "Tablet", + "Mobile" + ] +} diff --git a/proof_shadcn_theme/info_ko.json b/proof_shadcn_theme/info_ko.json new file mode 100644 index 0000000..76e1804 --- /dev/null +++ b/proof_shadcn_theme/info_ko.json @@ -0,0 +1,11 @@ +{ + "Title": "shadcn by Proof+Geist", + "Description": "Adds the shadcn theme to your file", + "Category": "Themes", + "Features": [], + "Optimized": [ + "Desktop", + "Tablet", + "Mobile" + ] +} diff --git a/proof_shadcn_theme/info_nl.json b/proof_shadcn_theme/info_nl.json new file mode 100644 index 0000000..76e1804 --- /dev/null +++ b/proof_shadcn_theme/info_nl.json @@ -0,0 +1,11 @@ +{ + "Title": "shadcn by Proof+Geist", + "Description": "Adds the shadcn theme to your file", + "Category": "Themes", + "Features": [], + "Optimized": [ + "Desktop", + "Tablet", + "Mobile" + ] +} diff --git a/proof_shadcn_theme/info_pt.json b/proof_shadcn_theme/info_pt.json new file mode 100644 index 0000000..76e1804 --- /dev/null +++ b/proof_shadcn_theme/info_pt.json @@ -0,0 +1,11 @@ +{ + "Title": "shadcn by Proof+Geist", + "Description": "Adds the shadcn theme to your file", + "Category": "Themes", + "Features": [], + "Optimized": [ + "Desktop", + "Tablet", + "Mobile" + ] +} diff --git a/proof_shadcn_theme/info_sv.json b/proof_shadcn_theme/info_sv.json new file mode 100644 index 0000000..76e1804 --- /dev/null +++ b/proof_shadcn_theme/info_sv.json @@ -0,0 +1,11 @@ +{ + "Title": "shadcn by Proof+Geist", + "Description": "Adds the shadcn theme to your file", + "Category": "Themes", + "Features": [], + "Optimized": [ + "Desktop", + "Tablet", + "Mobile" + ] +} diff --git a/proof_shadcn_theme/info_zh.json b/proof_shadcn_theme/info_zh.json new file mode 100644 index 0000000..76e1804 --- /dev/null +++ b/proof_shadcn_theme/info_zh.json @@ -0,0 +1,11 @@ +{ + "Title": "shadcn by Proof+Geist", + "Description": "Adds the shadcn theme to your file", + "Category": "Themes", + "Features": [], + "Optimized": [ + "Desktop", + "Tablet", + "Mobile" + ] +} diff --git a/proof_shadcn_theme/it.xml b/proof_shadcn_theme/it.xml new file mode 100644 index 0000000..ef70b08 --- /dev/null +++ b/proof_shadcn_theme/it.xml @@ -0,0 +1,98 @@ + + + com.fmi.basedirectory.CB285A0FD66A28850057FEB1F4A82D17 + Mizu/ + Mizu/ + com.fmi.basedirectory.Mizu/ + + + + com.fmi.basetable.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.basetable.__FMAddonTemplate_Metadata + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::1A6F6D8A5D201F2A21420B43C5345AE0 + __FMAddonTemplate_Version + __FMAddonTemplate_Version + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Version + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::3DF4202D460A0197901676D33510E2A9 + __FMAddonTemplate_GUID + __FMAddonTemplate_GUID + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_GUID + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::4C401D80F095E4875C589E7F30613788 + __FMAddonTemplate_PreviewImage + __FMAddonTemplate_PreviewImage + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_PreviewImage + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::58C8AA9702E724A8E8528A4EFD8E39BC + __FMAddonTemplate_Icon + __FMAddonTemplate_Icon + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Icon + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::5A65B734A19B7A9D40A8E233BCECC32B + __FMAddonTemplate_Desc + __FMAddonTemplate_Desc + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Desc + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::9C2DB678CD3FAB550FD3E0896225AC19 + __FMAddonTemplate_Clients + __FMAddonTemplate_Clients + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Clients + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::B0F082A2B4B8CD0DD4CC13D936B12D82 + __FMAddonTemplate_Attribution + __FMAddonTemplate_Attribution + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Attribution + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::BF67E2BFE93D889A4BB3ACAEF0833675 + __FMAddonTemplate_URL + __FMAddonTemplate_URL + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_URL + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::C3705CECC929CE96E6BCD1628F27214E + __FMAddonTemplate_Title + __FMAddonTemplate_Title + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Title + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::DFF29DF31A6BCD82433020A5B2096A06 + __FMAddonTemplate_Category + __FMAddonTemplate_Category + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Category + + + + com.fmi.calculation.text.E06123D571693687770B1259FAD99B28 + Proof Add-on Module + Proof Add-on Module + com.fmi.calculation.text.Proof Add-on Module + + + + com.fmi.tableoccurrence.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.tableoccurrence.__FMAddonTemplate_Metadata + diff --git a/proof_shadcn_theme/ja.xml b/proof_shadcn_theme/ja.xml new file mode 100644 index 0000000..ef70b08 --- /dev/null +++ b/proof_shadcn_theme/ja.xml @@ -0,0 +1,98 @@ + + + com.fmi.basedirectory.CB285A0FD66A28850057FEB1F4A82D17 + Mizu/ + Mizu/ + com.fmi.basedirectory.Mizu/ + + + + com.fmi.basetable.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.basetable.__FMAddonTemplate_Metadata + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::1A6F6D8A5D201F2A21420B43C5345AE0 + __FMAddonTemplate_Version + __FMAddonTemplate_Version + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Version + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::3DF4202D460A0197901676D33510E2A9 + __FMAddonTemplate_GUID + __FMAddonTemplate_GUID + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_GUID + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::4C401D80F095E4875C589E7F30613788 + __FMAddonTemplate_PreviewImage + __FMAddonTemplate_PreviewImage + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_PreviewImage + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::58C8AA9702E724A8E8528A4EFD8E39BC + __FMAddonTemplate_Icon + __FMAddonTemplate_Icon + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Icon + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::5A65B734A19B7A9D40A8E233BCECC32B + __FMAddonTemplate_Desc + __FMAddonTemplate_Desc + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Desc + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::9C2DB678CD3FAB550FD3E0896225AC19 + __FMAddonTemplate_Clients + __FMAddonTemplate_Clients + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Clients + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::B0F082A2B4B8CD0DD4CC13D936B12D82 + __FMAddonTemplate_Attribution + __FMAddonTemplate_Attribution + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Attribution + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::BF67E2BFE93D889A4BB3ACAEF0833675 + __FMAddonTemplate_URL + __FMAddonTemplate_URL + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_URL + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::C3705CECC929CE96E6BCD1628F27214E + __FMAddonTemplate_Title + __FMAddonTemplate_Title + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Title + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::DFF29DF31A6BCD82433020A5B2096A06 + __FMAddonTemplate_Category + __FMAddonTemplate_Category + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Category + + + + com.fmi.calculation.text.E06123D571693687770B1259FAD99B28 + Proof Add-on Module + Proof Add-on Module + com.fmi.calculation.text.Proof Add-on Module + + + + com.fmi.tableoccurrence.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.tableoccurrence.__FMAddonTemplate_Metadata + diff --git a/proof_shadcn_theme/ko.xml b/proof_shadcn_theme/ko.xml new file mode 100644 index 0000000..ef70b08 --- /dev/null +++ b/proof_shadcn_theme/ko.xml @@ -0,0 +1,98 @@ + + + com.fmi.basedirectory.CB285A0FD66A28850057FEB1F4A82D17 + Mizu/ + Mizu/ + com.fmi.basedirectory.Mizu/ + + + + com.fmi.basetable.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.basetable.__FMAddonTemplate_Metadata + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::1A6F6D8A5D201F2A21420B43C5345AE0 + __FMAddonTemplate_Version + __FMAddonTemplate_Version + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Version + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::3DF4202D460A0197901676D33510E2A9 + __FMAddonTemplate_GUID + __FMAddonTemplate_GUID + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_GUID + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::4C401D80F095E4875C589E7F30613788 + __FMAddonTemplate_PreviewImage + __FMAddonTemplate_PreviewImage + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_PreviewImage + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::58C8AA9702E724A8E8528A4EFD8E39BC + __FMAddonTemplate_Icon + __FMAddonTemplate_Icon + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Icon + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::5A65B734A19B7A9D40A8E233BCECC32B + __FMAddonTemplate_Desc + __FMAddonTemplate_Desc + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Desc + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::9C2DB678CD3FAB550FD3E0896225AC19 + __FMAddonTemplate_Clients + __FMAddonTemplate_Clients + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Clients + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::B0F082A2B4B8CD0DD4CC13D936B12D82 + __FMAddonTemplate_Attribution + __FMAddonTemplate_Attribution + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Attribution + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::BF67E2BFE93D889A4BB3ACAEF0833675 + __FMAddonTemplate_URL + __FMAddonTemplate_URL + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_URL + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::C3705CECC929CE96E6BCD1628F27214E + __FMAddonTemplate_Title + __FMAddonTemplate_Title + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Title + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::DFF29DF31A6BCD82433020A5B2096A06 + __FMAddonTemplate_Category + __FMAddonTemplate_Category + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Category + + + + com.fmi.calculation.text.E06123D571693687770B1259FAD99B28 + Proof Add-on Module + Proof Add-on Module + com.fmi.calculation.text.Proof Add-on Module + + + + com.fmi.tableoccurrence.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.tableoccurrence.__FMAddonTemplate_Metadata + diff --git a/proof_shadcn_theme/nl.xml b/proof_shadcn_theme/nl.xml new file mode 100644 index 0000000..ef70b08 --- /dev/null +++ b/proof_shadcn_theme/nl.xml @@ -0,0 +1,98 @@ + + + com.fmi.basedirectory.CB285A0FD66A28850057FEB1F4A82D17 + Mizu/ + Mizu/ + com.fmi.basedirectory.Mizu/ + + + + com.fmi.basetable.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.basetable.__FMAddonTemplate_Metadata + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::1A6F6D8A5D201F2A21420B43C5345AE0 + __FMAddonTemplate_Version + __FMAddonTemplate_Version + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Version + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::3DF4202D460A0197901676D33510E2A9 + __FMAddonTemplate_GUID + __FMAddonTemplate_GUID + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_GUID + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::4C401D80F095E4875C589E7F30613788 + __FMAddonTemplate_PreviewImage + __FMAddonTemplate_PreviewImage + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_PreviewImage + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::58C8AA9702E724A8E8528A4EFD8E39BC + __FMAddonTemplate_Icon + __FMAddonTemplate_Icon + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Icon + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::5A65B734A19B7A9D40A8E233BCECC32B + __FMAddonTemplate_Desc + __FMAddonTemplate_Desc + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Desc + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::9C2DB678CD3FAB550FD3E0896225AC19 + __FMAddonTemplate_Clients + __FMAddonTemplate_Clients + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Clients + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::B0F082A2B4B8CD0DD4CC13D936B12D82 + __FMAddonTemplate_Attribution + __FMAddonTemplate_Attribution + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Attribution + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::BF67E2BFE93D889A4BB3ACAEF0833675 + __FMAddonTemplate_URL + __FMAddonTemplate_URL + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_URL + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::C3705CECC929CE96E6BCD1628F27214E + __FMAddonTemplate_Title + __FMAddonTemplate_Title + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Title + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::DFF29DF31A6BCD82433020A5B2096A06 + __FMAddonTemplate_Category + __FMAddonTemplate_Category + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Category + + + + com.fmi.calculation.text.E06123D571693687770B1259FAD99B28 + Proof Add-on Module + Proof Add-on Module + com.fmi.calculation.text.Proof Add-on Module + + + + com.fmi.tableoccurrence.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.tableoccurrence.__FMAddonTemplate_Metadata + diff --git a/proof_shadcn_theme/preview.png b/proof_shadcn_theme/preview.png new file mode 100644 index 0000000..086703b Binary files /dev/null and b/proof_shadcn_theme/preview.png differ diff --git a/proof_shadcn_theme/pt.xml b/proof_shadcn_theme/pt.xml new file mode 100644 index 0000000..ef70b08 --- /dev/null +++ b/proof_shadcn_theme/pt.xml @@ -0,0 +1,98 @@ + + + com.fmi.basedirectory.CB285A0FD66A28850057FEB1F4A82D17 + Mizu/ + Mizu/ + com.fmi.basedirectory.Mizu/ + + + + com.fmi.basetable.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.basetable.__FMAddonTemplate_Metadata + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::1A6F6D8A5D201F2A21420B43C5345AE0 + __FMAddonTemplate_Version + __FMAddonTemplate_Version + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Version + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::3DF4202D460A0197901676D33510E2A9 + __FMAddonTemplate_GUID + __FMAddonTemplate_GUID + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_GUID + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::4C401D80F095E4875C589E7F30613788 + __FMAddonTemplate_PreviewImage + __FMAddonTemplate_PreviewImage + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_PreviewImage + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::58C8AA9702E724A8E8528A4EFD8E39BC + __FMAddonTemplate_Icon + __FMAddonTemplate_Icon + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Icon + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::5A65B734A19B7A9D40A8E233BCECC32B + __FMAddonTemplate_Desc + __FMAddonTemplate_Desc + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Desc + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::9C2DB678CD3FAB550FD3E0896225AC19 + __FMAddonTemplate_Clients + __FMAddonTemplate_Clients + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Clients + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::B0F082A2B4B8CD0DD4CC13D936B12D82 + __FMAddonTemplate_Attribution + __FMAddonTemplate_Attribution + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Attribution + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::BF67E2BFE93D889A4BB3ACAEF0833675 + __FMAddonTemplate_URL + __FMAddonTemplate_URL + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_URL + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::C3705CECC929CE96E6BCD1628F27214E + __FMAddonTemplate_Title + __FMAddonTemplate_Title + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Title + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::DFF29DF31A6BCD82433020A5B2096A06 + __FMAddonTemplate_Category + __FMAddonTemplate_Category + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Category + + + + com.fmi.calculation.text.E06123D571693687770B1259FAD99B28 + Proof Add-on Module + Proof Add-on Module + com.fmi.calculation.text.Proof Add-on Module + + + + com.fmi.tableoccurrence.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.tableoccurrence.__FMAddonTemplate_Metadata + diff --git a/proof_shadcn_theme/records_de.xml b/proof_shadcn_theme/records_de.xml new file mode 100644 index 0000000..e13f76f Binary files /dev/null and b/proof_shadcn_theme/records_de.xml differ diff --git a/proof_shadcn_theme/records_en.xml b/proof_shadcn_theme/records_en.xml new file mode 100644 index 0000000..e13f76f Binary files /dev/null and b/proof_shadcn_theme/records_en.xml differ diff --git a/proof_shadcn_theme/records_es.xml b/proof_shadcn_theme/records_es.xml new file mode 100644 index 0000000..e13f76f Binary files /dev/null and b/proof_shadcn_theme/records_es.xml differ diff --git a/proof_shadcn_theme/records_fr.xml b/proof_shadcn_theme/records_fr.xml new file mode 100644 index 0000000..e13f76f Binary files /dev/null and b/proof_shadcn_theme/records_fr.xml differ diff --git a/proof_shadcn_theme/records_it.xml b/proof_shadcn_theme/records_it.xml new file mode 100644 index 0000000..e13f76f Binary files /dev/null and b/proof_shadcn_theme/records_it.xml differ diff --git a/proof_shadcn_theme/records_ja.xml b/proof_shadcn_theme/records_ja.xml new file mode 100644 index 0000000..e13f76f Binary files /dev/null and b/proof_shadcn_theme/records_ja.xml differ diff --git a/proof_shadcn_theme/records_ko.xml b/proof_shadcn_theme/records_ko.xml new file mode 100644 index 0000000..e13f76f Binary files /dev/null and b/proof_shadcn_theme/records_ko.xml differ diff --git a/proof_shadcn_theme/records_nl.xml b/proof_shadcn_theme/records_nl.xml new file mode 100644 index 0000000..e13f76f Binary files /dev/null and b/proof_shadcn_theme/records_nl.xml differ diff --git a/proof_shadcn_theme/records_pt.xml b/proof_shadcn_theme/records_pt.xml new file mode 100644 index 0000000..e13f76f Binary files /dev/null and b/proof_shadcn_theme/records_pt.xml differ diff --git a/proof_shadcn_theme/records_sv.xml b/proof_shadcn_theme/records_sv.xml new file mode 100644 index 0000000..e13f76f Binary files /dev/null and b/proof_shadcn_theme/records_sv.xml differ diff --git a/proof_shadcn_theme/records_zh.xml b/proof_shadcn_theme/records_zh.xml new file mode 100644 index 0000000..e13f76f Binary files /dev/null and b/proof_shadcn_theme/records_zh.xml differ diff --git a/proof_shadcn_theme/sv.xml b/proof_shadcn_theme/sv.xml new file mode 100644 index 0000000..ef70b08 --- /dev/null +++ b/proof_shadcn_theme/sv.xml @@ -0,0 +1,98 @@ + + + com.fmi.basedirectory.CB285A0FD66A28850057FEB1F4A82D17 + Mizu/ + Mizu/ + com.fmi.basedirectory.Mizu/ + + + + com.fmi.basetable.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.basetable.__FMAddonTemplate_Metadata + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::1A6F6D8A5D201F2A21420B43C5345AE0 + __FMAddonTemplate_Version + __FMAddonTemplate_Version + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Version + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::3DF4202D460A0197901676D33510E2A9 + __FMAddonTemplate_GUID + __FMAddonTemplate_GUID + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_GUID + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::4C401D80F095E4875C589E7F30613788 + __FMAddonTemplate_PreviewImage + __FMAddonTemplate_PreviewImage + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_PreviewImage + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::58C8AA9702E724A8E8528A4EFD8E39BC + __FMAddonTemplate_Icon + __FMAddonTemplate_Icon + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Icon + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::5A65B734A19B7A9D40A8E233BCECC32B + __FMAddonTemplate_Desc + __FMAddonTemplate_Desc + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Desc + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::9C2DB678CD3FAB550FD3E0896225AC19 + __FMAddonTemplate_Clients + __FMAddonTemplate_Clients + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Clients + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::B0F082A2B4B8CD0DD4CC13D936B12D82 + __FMAddonTemplate_Attribution + __FMAddonTemplate_Attribution + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Attribution + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::BF67E2BFE93D889A4BB3ACAEF0833675 + __FMAddonTemplate_URL + __FMAddonTemplate_URL + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_URL + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::C3705CECC929CE96E6BCD1628F27214E + __FMAddonTemplate_Title + __FMAddonTemplate_Title + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Title + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::DFF29DF31A6BCD82433020A5B2096A06 + __FMAddonTemplate_Category + __FMAddonTemplate_Category + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Category + + + + com.fmi.calculation.text.E06123D571693687770B1259FAD99B28 + Proof Add-on Module + Proof Add-on Module + com.fmi.calculation.text.Proof Add-on Module + + + + com.fmi.tableoccurrence.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.tableoccurrence.__FMAddonTemplate_Metadata + diff --git a/proof_shadcn_theme/template.xml b/proof_shadcn_theme/template.xml new file mode 100644 index 0000000..c82b24d Binary files /dev/null and b/proof_shadcn_theme/template.xml differ diff --git a/proof_shadcn_theme/zh.xml b/proof_shadcn_theme/zh.xml new file mode 100644 index 0000000..ef70b08 --- /dev/null +++ b/proof_shadcn_theme/zh.xml @@ -0,0 +1,98 @@ + + + com.fmi.basedirectory.CB285A0FD66A28850057FEB1F4A82D17 + Mizu/ + Mizu/ + com.fmi.basedirectory.Mizu/ + + + + com.fmi.basetable.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.basetable.__FMAddonTemplate_Metadata + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::1A6F6D8A5D201F2A21420B43C5345AE0 + __FMAddonTemplate_Version + __FMAddonTemplate_Version + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Version + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::3DF4202D460A0197901676D33510E2A9 + __FMAddonTemplate_GUID + __FMAddonTemplate_GUID + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_GUID + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::4C401D80F095E4875C589E7F30613788 + __FMAddonTemplate_PreviewImage + __FMAddonTemplate_PreviewImage + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_PreviewImage + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::58C8AA9702E724A8E8528A4EFD8E39BC + __FMAddonTemplate_Icon + __FMAddonTemplate_Icon + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Icon + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::5A65B734A19B7A9D40A8E233BCECC32B + __FMAddonTemplate_Desc + __FMAddonTemplate_Desc + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Desc + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::9C2DB678CD3FAB550FD3E0896225AC19 + __FMAddonTemplate_Clients + __FMAddonTemplate_Clients + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Clients + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::B0F082A2B4B8CD0DD4CC13D936B12D82 + __FMAddonTemplate_Attribution + __FMAddonTemplate_Attribution + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Attribution + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::BF67E2BFE93D889A4BB3ACAEF0833675 + __FMAddonTemplate_URL + __FMAddonTemplate_URL + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_URL + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::C3705CECC929CE96E6BCD1628F27214E + __FMAddonTemplate_Title + __FMAddonTemplate_Title + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Title + + + + com.fmi.basetable.field.__FMAddonTemplate_Metadata::DFF29DF31A6BCD82433020A5B2096A06 + __FMAddonTemplate_Category + __FMAddonTemplate_Category + com.fmi.basetable.field.__FMAddonTemplate_Metadata::__FMAddonTemplate_Category + + + + com.fmi.calculation.text.E06123D571693687770B1259FAD99B28 + Proof Add-on Module + Proof Add-on Module + com.fmi.calculation.text.Proof Add-on Module + + + + com.fmi.tableoccurrence.A72664F13DDFEACC5F6AAC99DE88BC03 + __FMAddonTemplate_Metadata + __FMAddonTemplate_Metadata + com.fmi.tableoccurrence.__FMAddonTemplate_Metadata + diff --git a/tools/color_transform.py b/tools/color_transform.py new file mode 100644 index 0000000..8e4797c --- /dev/null +++ b/tools/color_transform.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python3 +""" +Color transformation script for shadcn theme. + +Reads a FileMaker template.xml (UTF-16 LE with BOM), applies ordered +find-and-replace on rgba color values within the CSS CDATA block, +and writes back preserving encoding exactly. + +Usage: + python3 tools/color_transform.py [--dry-run] +""" + +import re +import sys +from collections import OrderedDict + +TEMPLATE_PATH = "proof_shadcn_theme/template.xml" + +# ─── shadcn target palette (FileMaker rgba format) ─────────────────── +# background: rgba(100%,100%,100%,1) — page/card backgrounds +# foreground: rgba(14.1%,14.1%,14.1%,1) — primary text +# primary: rgba(18%,18%,18%,1) — buttons, active states +# primary-foreground: rgba(98%,98%,98%,1) — text on primary surfaces +# secondary: rgba(96.1%,96.1%,96.1%,1) — hover backgrounds, alt rows +# muted-foreground: rgba(56.5%,56.5%,56.5%,1) — placeholders, secondary labels +# border: rgba(92.2%,92.2%,92.2%,1) — all borders +# ring: rgba(70.2%,70.2%,70.2%,1) — focus ring +# destructive: keep current red — error states + +# ─── Color mapping ────────────────────────────────────────────────── +# Order matters: more specific values first to avoid partial replacements. +# Each entry: (old_rgba, new_rgba, category_description) + +COLOR_MAP = OrderedDict([ + # ── Batch 1: Blue accents → primary (dark gray) ────────────────── + # Main blue accent (232 occurrences - biggest single color) + ("rgba(14.5098%,40.3922%,96.0784%,1)", "rgba(18%,18%,18%,1)"), + # Blue accent with alpha (for subtle backgrounds) + ("rgba(14.5098%,40.3922%,96.0784%,0.0740582)", "rgba(18%,18%,18%,0.07)"), + # Saturated blues → primary + ("rgba(0%,43.9216%,81.1765%,1)", "rgba(18%,18%,18%,1)"), + ("rgba(0%,47.8431%,100%,1)", "rgba(18%,18%,18%,1)"), + ("rgba(0%,25.4095%,80.0784%,1)", "rgba(18%,18%,18%,1)"), + ("rgba(0%,40.1882%,84%,1)", "rgba(18%,18%,18%,1)"), + # Darker blues → primary + ("rgba(10.1961%,34.5098%,88.2353%,1)", "rgba(18%,18%,18%,1)"), + ("rgba(2.7451%,19.6078%,58.8235%,1)", "rgba(14.1%,14.1%,14.1%,1)"), + ("rgba(10.0502%,25.829%,46.7451%,1)", "rgba(14.1%,14.1%,14.1%,1)"), + ("rgba(0%,16.0784%,22.3529%,1)", "rgba(14.1%,14.1%,14.1%,1)"), + + # ── Batch 2: Blue-tinted light backgrounds → secondary/neutral ─── + # Light blue tints → neutral near-white + ("rgba(75.2941%,92.9412%,99.6078%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(89.0196%,94.902%,99.2157%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(96.0784%,97.2549%,98.0392%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(95.6863%,96.4706%,98.0392%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(95.6863%,96.8627%,97.6471%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(92.3695%,95.9839%,100%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(90.1961%,93.7255%,97.6471%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(70.1961%,89.4118%,98.8235%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(70.1961%,89.8039%,98.8235%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(98.0392%,98.0392%,100%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + # Cyan/teal-tinted colors → neutral + ("rgba(30.1961%,78.8235%,96.0784%,1)", "rgba(70.2%,70.2%,70.2%,1)"), + ("rgba(15.6863%,71.3726%,96.4706%,1)", "rgba(56.5%,56.5%,56.5%,1)"), + ("rgba(16.0784%,71.3726%,96.4706%,1)", "rgba(56.5%,56.5%,56.5%,1)"), + ("rgba(0%,72.9412%,98.4314%,1)", "rgba(70.2%,70.2%,70.2%,1)"), + ("rgba(0%,73.3333%,98.4314%,1)", "rgba(70.2%,70.2%,70.2%,1)"), + ("rgba(1.56863%,72.549%,98.4314%,1)", "rgba(70.2%,70.2%,70.2%,1)"), + ("rgba(49.4118%,73.7255%,100%,1)", "rgba(70.2%,70.2%,70.2%,1)"), + ("rgba(50.1961%,65.8824%,100%,1)", "rgba(70.2%,70.2%,70.2%,1)"), + # Teal/green-blue mid-tones → muted-foreground + ("rgba(12.549%,62.3529%,80.3922%,1)", "rgba(56.5%,56.5%,56.5%,1)"), + ("rgba(12.9129%,62.6278%,80.7059%,1)", "rgba(56.5%,56.5%,56.5%,1)"), + ("rgba(67.2722%,76.1324%,82.0392%,1)", "rgba(80%,80%,80%,1)"), + + # ── Batch 3: Purple/blue-cast grays → neutral grays ────────────── + # Purple-cast grays used in borders and backgrounds + ("rgba(78.4314%,78.0392%,80%,1)", "rgba(80%,80%,80%,1)"), + ("rgba(78.4314%,77.6471%,80%,1)", "rgba(80%,80%,80%,1)"), + ("rgba(93.7255%,93.7255%,95.6863%,1)", "rgba(92.2%,92.2%,92.2%,1)"), + ("rgba(97.6471%,96.8627%,98.0392%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(97.7024%,97.1215%,98.1489%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + # Purple-cast mid-grays + ("rgba(22.7451%,20.3922%,25.098%,1)", "rgba(22.3529%,22.3529%,22.3529%,1)"), + ("rgba(22.9226%,20.6687%,25.1765%,1)", "rgba(22.3529%,22.3529%,22.3529%,1)"), + ("rgba(40.7843%,40.3922%,41.1765%,1)", "rgba(38.3529%,38.3529%,38.3529%,1)"), + ("rgba(45.098%,44.7059%,45.4902%,1)", "rgba(45.8824%,45.8824%,45.8824%,1)"), + ("rgba(45.098%,44.7059%,45.4902%,0.4)", "rgba(45.8824%,45.8824%,45.8824%,0.4)"), + ("rgba(45.9162%,56.2971%,60.4495%,0.579236)", "rgba(56.5%,56.5%,56.5%,0.58)"), + ("rgba(69.0196%,74.5098%,77.2549%,1)", "rgba(74.1961%,74.1961%,74.1961%,1)"), + ("rgba(96.3922%,15.4227%,83.3581%,1)", "rgba(56.5%,56.5%,56.5%,1)"), + ("rgba(97.1487%,89.2283%,100%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(80.3922%,0%,67.451%,1)", "rgba(56.5%,56.5%,56.5%,1)"), + + # ── Batch 4: Text colors → foreground / muted-foreground ──────── + # Near-black text shades → foreground + ("rgba(4.31373%,4.31373%,4.31373%,1)", "rgba(14.1%,14.1%,14.1%,1)"), + ("rgba(6.27451%,6.27451%,6.27451%,1)", "rgba(14.1%,14.1%,14.1%,1)"), + ("rgba(6.35294%,6.35294%,6.35294%,1)", "rgba(14.1%,14.1%,14.1%,1)"), + ("rgba(8.62745%,8.62745%,8.62745%,1)", "rgba(14.1%,14.1%,14.1%,1)"), + ("rgba(10.1961%,10.1961%,10.1961%,1)", "rgba(14.1%,14.1%,14.1%,1)"), + ("rgba(20.3922%,20.3922%,20.3922%,1)", "rgba(14.1%,14.1%,14.1%,1)"), + # Mid-gray text → muted-foreground + ("rgba(43.5294%,43.5294%,43.5294%,1)", "rgba(56.5%,56.5%,56.5%,1)"), + ("rgba(45.8824%,45.8824%,45.8824%,1)", "rgba(56.5%,56.5%,56.5%,1)"), + ("rgba(51.7647%,51.7647%,51.7647%,1)", "rgba(56.5%,56.5%,56.5%,1)"), + ("rgba(59.2157%,59.2157%,59.2157%,1)", "rgba(56.5%,56.5%,56.5%,1)"), + ("rgba(60.3922%,60.3922%,60.3922%,1)", "rgba(56.5%,56.5%,56.5%,1)"), + + # ── Batch 5: Border grays → unified border color ──────────────── + ("rgba(87.8431%,87.8431%,87.8431%,1)", "rgba(92.2%,92.2%,92.2%,1)"), + ("rgba(90.1961%,90.1961%,90.1961%,1)", "rgba(92.2%,92.2%,92.2%,1)"), + ("rgba(92.1569%,92.1569%,92.1569%,1)", "rgba(92.2%,92.2%,92.2%,1)"), + ("rgba(93.3333%,93.3333%,93.3333%,1)", "rgba(92.2%,92.2%,92.2%,1)"), + ("rgba(95.6863%,95.6863%,95.6863%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(96.0784%,96.0784%,96.0784%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + ("rgba(96.4706%,96.4706%,96.4706%,1)", "rgba(96.1%,96.1%,96.1%,1)"), + + # ── Batch 6: Dark surfaces → foreground ────────────────────────── + ("rgba(22.3529%,22.3529%,22.3529%,1)", "rgba(18%,18%,18%,1)"), + ("rgba(25.8824%,25.8824%,25.8824%,1)", "rgba(18%,18%,18%,1)"), + ("rgba(29.8039%,29.8039%,29.8039%,1)", "rgba(18%,18%,18%,1)"), + ("rgba(30.1961%,30.1961%,30.1961%,1)", "rgba(18%,18%,18%,1)"), + ("rgba(36.0784%,36.0784%,36.0784%,1)", "rgba(18%,18%,18%,1)"), + ("rgba(38.0392%,38.0392%,38.0392%,1)", "rgba(18%,18%,18%,1)"), + ("rgba(38.3529%,38.3529%,38.3529%,1)", "rgba(18%,18%,18%,1)"), +]) + +# Colors to leave alone (no mapping needed, just documenting): +# rgba(0%,0%,0%,0) — transparent +# rgba(0%,0%,0%,1) — pure black +# rgba(100%,100%,100%,0) — transparent white +# rgba(100%,100%,100%,1) — white +# rgba(0%,0%,0%,0.101825) — shadow alpha +# rgba(0%,0%,0%,0.15) — shadow alpha +# rgba(100%,80%,0%,1) — yellow/warning +# rgba(42.3529%,10.1961%,9.41177%,1) — destructive dark +# rgba(66.6667%,17.2549%,16.4706%,1) — destructive +# rgba(78.8235%,20.3922%,19.6078%,1) — destructive light +# rgba(78.8235%,20.7843%,19.6078%,1) — destructive light variant +# rgba(14.1176%,14.1176%,14.1176%,1) — already matches foreground target + + +def read_template(path): + """Read UTF-16 LE file with BOM, return (bom_bytes, text).""" + with open(path, "rb") as f: + raw = f.read() + + # Check for BOM + if raw[:2] == b"\xff\xfe": + bom = raw[:2] + text = raw[2:].decode("utf-16-le") + else: + bom = b"" + text = raw.decode("utf-16-le") + + return bom, text + + +def write_template(path, bom, text): + """Write back with original BOM and encoding.""" + with open(path, "wb") as f: + f.write(bom) + f.write(text.encode("utf-16-le")) + + +def find_css_cdata(text): + """Find the CSS CDATA block boundaries. Returns (start, end) of inner content.""" + # The CSS CDATA starts with "/* Object Styles */" + marker = "", cdata_start) + if cdata_end == -1: + raise ValueError("Could not find end of CSS CDATA block") + + return cdata_start, cdata_end + + +def apply_color_map(css_text, color_map, dry_run=False): + """Apply ordered color replacements to CSS text. Returns (new_text, stats).""" + stats = OrderedDict() + result = css_text + + for old_color, new_color in color_map.items(): + count = result.count(old_color) + if count > 0: + if not dry_run: + result = result.replace(old_color, new_color) + stats[old_color] = {"new": new_color, "count": count} + + return result, stats + + +def main(): + dry_run = "--dry-run" in sys.argv + + print(f"Reading {TEMPLATE_PATH}...") + bom, text = read_template(TEMPLATE_PATH) + print(f" File size: {len(text)} characters, BOM: {'yes' if bom else 'no'}") + + css_start, css_end = find_css_cdata(text) + css_text = text[css_start:css_end] + print(f" CSS block: {len(css_text)} characters ({css_start}..{css_end})") + + # Count total rgba values before + rgba_before = len(re.findall(r"rgba\([^)]+\)", css_text)) + print(f" Total rgba values: {rgba_before}") + + # Apply replacements + mode = "DRY RUN" if dry_run else "APPLYING" + print(f"\n{mode} color replacements...") + + new_css, stats = apply_color_map(css_text, COLOR_MAP, dry_run=dry_run) + + total_replacements = 0 + for old_color, info in stats.items(): + print(f" {info['count']:4d}x {old_color}") + print(f" → {info['new']}") + total_replacements += info["count"] + + print(f"\nTotal replacements: {total_replacements}") + + if not dry_run: + # Reconstruct file + new_text = text[:css_start] + new_css + text[css_end:] + + # Verify unique rgba values remaining + unique_after = sorted(set(re.findall(r"rgba\([^)]+\)", new_css))) + print(f"\nUnique rgba values remaining: {len(unique_after)}") + for v in unique_after: + count = new_css.count(v) + print(f" {count:4d}x {v}") + + write_template(TEMPLATE_PATH, bom, new_text) + print(f"\nWritten to {TEMPLATE_PATH}") + + # Verify encoding roundtrip + _, verify_text = read_template(TEMPLATE_PATH) + if verify_text == new_text: + print("Encoding verification: PASSED") + else: + print("ERROR: Encoding verification FAILED!") + sys.exit(1) + else: + print("\nDry run complete. Use without --dry-run to apply.") + + +if __name__ == "__main__": + main() diff --git a/tools/element_refinements.py b/tools/element_refinements.py new file mode 100644 index 0000000..def26aa --- /dev/null +++ b/tools/element_refinements.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python3 +""" +Phase 2: Element-specific refinements for shadcn theme. + +Applies targeted CSS rule modifications that can't be done with global +find-and-replace (semantically different elements need different treatment). +""" + +import re +import sys + + +TEMPLATE_PATH = "proof_shadcn_theme/template.xml" + + +def read_template(path): + with open(path, "rb") as f: + raw = f.read() + if raw[:2] == b"\xff\xfe": + bom = raw[:2] + text = raw[2:].decode("utf-16-le") + else: + bom = b"" + text = raw.decode("utf-16-le") + return bom, text + + +def write_template(path, bom, text): + with open(path, "wb") as f: + f.write(bom) + f.write(text.encode("utf-16-le")) + + +def find_css_cdata(text): + marker = "", start) + return start, end + + +def replace_rule(css, selector, old_props, new_props): + """Replace properties within a specific CSS rule block. + + Finds the rule matching `selector`, then replaces `old_props` with + `new_props` within that rule only. + """ + # Find the selector + idx = css.find(selector) + if idx == -1: + print(f" WARNING: selector not found: {selector}") + return css, False + + # Find the opening and closing braces + brace_start = css.find("{", idx) + brace_end = css.find("}", brace_start) + if brace_start == -1 or brace_end == -1: + print(f" WARNING: could not find braces for: {selector}") + return css, False + + rule_content = css[brace_start:brace_end + 1] + if old_props not in rule_content: + print(f" WARNING: props not found in {selector}: {old_props[:50]}...") + return css, False + + new_rule = rule_content.replace(old_props, new_props, 1) + css = css[:brace_start] + new_rule + css[brace_end + 1:] + return css, True + + +def insert_props_in_rule(css, selector, new_props): + """Insert new properties at the end of a rule block (before closing brace).""" + idx = css.find(selector) + if idx == -1: + print(f" WARNING: selector not found: {selector}") + return css, False + + brace_start = css.find("{", idx) + brace_end = css.find("}", brace_start) + + # Insert before the closing brace + css = css[:brace_end] + new_props + "\n" + css[brace_end:] + return css, True + + +def apply_input_full_border(css): + """Convert bottom-border-only inputs to full-border with radius.""" + print("\n--- Input fields: bottom-border → full border ---") + count = 0 + + # Elements that currently have bottom-border-only + for element in ["edit_box", "pop_up", "drop_down"]: + selector = f"{element}:normal .self" + + # Change border styles from none to solid + old = ( + "\tborder-top-style: none;\n" + "\tborder-right-style: none;\n" + "\tborder-bottom-style: solid;\n" + "\tborder-left-style: none;" + ) + new = ( + "\tborder-top-style: solid;\n" + "\tborder-right-style: solid;\n" + "\tborder-bottom-style: solid;\n" + "\tborder-left-style: solid;\n" + "\tborder-top-right-radius: 6pt 6pt;\n" + "\tborder-bottom-right-radius: 6pt 6pt;\n" + "\tborder-bottom-left-radius: 6pt 6pt;\n" + "\tborder-top-left-radius: 6pt 6pt;" + ) + + css, ok = replace_rule(css, selector, old, new) + if ok: + print(f" {element}: full border + 6pt radius") + count += 1 + + # Also update the border color from border gray to a slightly lighter + # shade for normal state (shadcn inputs use border color) + print(f" Updated {count} input elements") + return css + + +def apply_checkbox_radio_filled(css): + """Make checkbox/radio dark-filled when checked (shadcn pattern).""" + print("\n--- Checkbox/radio: dark filled when checked ---") + + # Checkbox checked icon: add dark background + white icon + old = ( + "checkbox_set:checked .icon\n" + "{\n" + "\t-fm-icon: modern-check;\n" + "\t-fm-icon-color: rgba(0%,0%,0%,1);\n" + "}" + ) + new = ( + "checkbox_set:checked .icon\n" + "{\n" + "\tbackground-color: rgba(18%,18%,18%,1);\n" + "\tborder-top-color: rgba(18%,18%,18%,1);\n" + "\tborder-right-color: rgba(18%,18%,18%,1);\n" + "\tborder-bottom-color: rgba(18%,18%,18%,1);\n" + "\tborder-left-color: rgba(18%,18%,18%,1);\n" + "\t-fm-icon: modern-check;\n" + "\t-fm-icon-color: rgba(100%,100%,100%,1);\n" + "}" + ) + css = css.replace(old, new, 1) + print(" checkbox_set:checked — dark bg + white check") + + # Radio checked icon: add dark background + white icon + old = ( + "radio_set:checked .icon\n" + "{\n" + "\t-fm-icon: radio;\n" + "\t-fm-icon-color: rgba(0%,0%,0%,1);\n" + "}" + ) + new = ( + "radio_set:checked .icon\n" + "{\n" + "\tbackground-color: rgba(18%,18%,18%,1);\n" + "\tborder-top-color: rgba(18%,18%,18%,1);\n" + "\tborder-right-color: rgba(18%,18%,18%,1);\n" + "\tborder-bottom-color: rgba(18%,18%,18%,1);\n" + "\tborder-left-color: rgba(18%,18%,18%,1);\n" + "\t-fm-icon: radio;\n" + "\t-fm-icon-color: rgba(100%,100%,100%,1);\n" + "}" + ) + css = css.replace(old, new, 1) + print(" radio_set:checked — dark bg + white dot") + + # Also handle FM-UUID instance overrides for checkbox/radio checked + # Find all checkbox_set.FM-*:checked .icon and radio_set.FM-*:checked .icon + pattern = re.compile( + r'((?:checkbox_set|radio_set)\.FM-[^:]+:checked \.icon\n\{\n)' + r'(\t-fm-icon: (?:modern-check|radio);\n' + r'\t-fm-icon-color: rgba\(0%,0%,0%,1\);\n\})' + ) + def replace_instance_checked(m): + prefix = m.group(1) + icon_line = "\t-fm-icon: modern-check;" if "checkbox" in m.group(0) else "\t-fm-icon: radio;" + return ( + prefix + + "\tbackground-color: rgba(18%,18%,18%,1);\n" + + "\tborder-top-color: rgba(18%,18%,18%,1);\n" + + "\tborder-right-color: rgba(18%,18%,18%,1);\n" + + "\tborder-bottom-color: rgba(18%,18%,18%,1);\n" + + "\tborder-left-color: rgba(18%,18%,18%,1);\n" + + icon_line + "\n" + + "\t-fm-icon-color: rgba(100%,100%,100%,1);\n" + + "}" + ) + + css, instance_count = pattern.subn(replace_instance_checked, css) + if instance_count: + print(f" {instance_count} FM-UUID instance overrides also updated") + + return css + + +def apply_filled_button_fixes(css): + """Ensure filled primary buttons have correct light text on hover/press.""" + print("\n--- Filled buttons: ensure light text in all states ---") + + # Find filled button instances and fix their hover states + # Pattern: button.FM-*:hover .self with background going to light color + # but text color not explicitly set to dark + # For filled buttons, hover should stay dark bg or go slightly lighter + # Current issue: some filled buttons hover to rgba(96.1%) bg (light) but + # don't set text color, so text stays white on light bg + + # Fix filled button hover states: if hover bg is light, set text color dark + pattern = re.compile( + r'(button\.FM-[A-F0-9-]+:hover \.self\n\{\n' + r'\tbackground-image: none;\n' + r'\tbackground-color: rgba\(96\.1%,96\.1%,96\.1%,1\);\n' + r'\tborder-image-source: none;\n' + r'\})' + ) + + def add_text_color_to_hover(m): + # Replace closing brace with text color + closing brace + block = m.group(1) + return block.replace( + "\tborder-image-source: none;\n}", + "\tborder-image-source: none;\n" + "\tcolor: rgba(14.1%,14.1%,14.1%,1);\n}" + ) + + css, count = pattern.subn(add_text_color_to_hover, css) + print(f" Added dark text color to {count} button hover states") + + # Fix icon colors for filled buttons: normal icon should be white + # Find filled buttons (bg: 18%) and set their icon color to white + lines = css.split("\n") + i = 0 + icon_fixes = 0 + while i < len(lines): + line = lines[i] + # Find filled button normal .self blocks + if re.match(r'button\.FM-[A-F0-9-]+:normal \.self', line): + # Check if this is a filled button (has dark bg) + block_end = i + for j in range(i + 1, min(i + 30, len(lines))): + if lines[j].strip() == "}": + block_end = j + break + block = "\n".join(lines[i:block_end + 1]) + if "background-color: rgba(18%,18%,18%,1)" in block: + # This is a filled button - find its icon rule + uuid = re.search(r'FM-[A-F0-9-]+', line).group(0) + icon_selector = f"button.{uuid}:normal .icon" + icon_idx = css.find(icon_selector) + if icon_idx != -1: + # Check if icon color is black and change to white + old_icon = f"{icon_selector}\n{{\n\t-fm-icon-color: rgba(0%,0%,0%,1);\n}}" + new_icon = f"{icon_selector}\n{{\n\t-fm-icon-color: rgba(100%,100%,100%,1);\n}}" + if old_icon in css: + css = css.replace(old_icon, new_icon, 1) + icon_fixes += 1 + i += 1 + + print(f" Fixed {icon_fixes} filled button icon colors to white") + return css + + +def apply_placeholder_standardization(css): + """Standardize placeholder text to muted-foreground.""" + print("\n--- Placeholder text: standardize to muted-foreground ---") + + # Some placeholders use rgba(80%,...), some rgba(70.2%,...) + # Standardize to muted-foreground rgba(56.5%,...) + old = "color: rgba(80%,80%,80%,1)" + count_before = css.count(old) + + # Only replace in placeholder rules + pattern = re.compile( + r'(:placeholder \.self\n\{\n\tcolor: )rgba\(80%,80%,80%,1\)' + ) + css, count = pattern.subn(r'\1rgba(56.5%,56.5%,56.5%,1)', css) + print(f" Updated {count} placeholder colors to muted-foreground") + + return css + + +def main(): + dry_run = "--dry-run" in sys.argv + + print(f"Reading {TEMPLATE_PATH}...") + bom, text = read_template(TEMPLATE_PATH) + + css_start, css_end = find_css_cdata(text) + css = text[css_start:css_end] + print(f" CSS block: {len(css)} characters") + + # Apply refinements + css = apply_input_full_border(css) + css = apply_checkbox_radio_filled(css) + css = apply_filled_button_fixes(css) + css = apply_placeholder_standardization(css) + + if not dry_run: + new_text = text[:css_start] + css + text[css_end:] + write_template(TEMPLATE_PATH, bom, new_text) + print(f"\nWritten to {TEMPLATE_PATH}") + + # Verify + _, verify = read_template(TEMPLATE_PATH) + if verify == new_text: + print("Encoding verification: PASSED") + else: + print("ERROR: Encoding verification FAILED!") + sys.exit(1) + else: + print("\nDry run complete.") + + +if __name__ == "__main__": + main()