feat: robots.txt editor and tester screen
- golem15.seo.robots singleton (UI-SPEC C10): staging callout and the served file (P4); the plugin's own extension adds the editor, the tester and the AI bots tab, saved to the robots row with history - field type robotstxt (E4, live lint, size meter; Decode refuses over 500 KB) and widget golem15-seo-robotstester (E5) on robots_test, which tests the unsaved text and switches through grobotstxt - saving rules that block a noindex address answers robots.blocks_noindex
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
/* SEO field elements (UI-SPEC C4, C5, C6, C14). Light DOM, every rule
|
||||
/* SEO field elements (UI-SPEC C4, C5, C6, C10, C14). Light DOM, every rule
|
||||
scoped under its element tag, colours from the public --c-* variables
|
||||
only (except the E-1 mimic palette inside golem15-seo-serp .serp-card). */
|
||||
|
||||
golem15-seo-text,
|
||||
golem15-seo-robots,
|
||||
golem15-seo-serp,
|
||||
golem15-seo-image {
|
||||
golem15-seo-image,
|
||||
golem15-seo-robotstxt,
|
||||
golem15-seo-robotstester {
|
||||
display: block;
|
||||
color: var(--c-text);
|
||||
font-size: 14px;
|
||||
@@ -440,6 +442,187 @@ golem15-seo-image.seo-image--invalid .seo-image__img {
|
||||
border-color: var(--c-danger);
|
||||
}
|
||||
|
||||
/* E4 golem15-seo-robotstxt */
|
||||
golem15-seo-robotstxt .seo-robotstxt__control {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 320px;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid var(--c-border-strong);
|
||||
border-radius: 10px;
|
||||
background: var(--c-surface);
|
||||
color: var(--c-text);
|
||||
font-family: 'DM Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
white-space: pre;
|
||||
overflow-x: auto;
|
||||
resize: vertical;
|
||||
transition: border-color 150ms, box-shadow 150ms;
|
||||
}
|
||||
|
||||
golem15-seo-robotstxt .seo-robotstxt__control:focus {
|
||||
outline: none;
|
||||
border-color: var(--c-primary);
|
||||
box-shadow: 0 0 0 3px var(--c-ring);
|
||||
}
|
||||
|
||||
golem15-seo-robotstxt.seo-robotstxt--invalid .seo-robotstxt__control,
|
||||
golem15-seo-robotstxt.seo-robotstxt--over .seo-robotstxt__control {
|
||||
border-color: var(--c-danger);
|
||||
}
|
||||
|
||||
golem15-seo-robotstxt .seo-robotstxt__lint {
|
||||
margin-top: 8px;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
background: var(--c-subtle);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
golem15-seo-robotstxt .seo-robotstxt__finding {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 6px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
golem15-seo-robotstxt .seo-robotstxt__finding + .seo-robotstxt__finding {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
golem15-seo-robotstxt .seo-robotstxt__finding .seo-icon {
|
||||
flex: none;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
golem15-seo-robotstxt .seo-robotstxt__finding--clean {
|
||||
color: var(--c-ok-text, var(--c-text));
|
||||
}
|
||||
|
||||
golem15-seo-robotstxt .seo-robotstxt__more {
|
||||
margin-top: 4px;
|
||||
color: var(--c-muted);
|
||||
}
|
||||
|
||||
golem15-seo-robotstxt .seo-robotstxt__size {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
margin-top: 6px;
|
||||
color: var(--c-muted);
|
||||
font-size: 13px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
golem15-seo-robotstxt .seo-robotstxt__over {
|
||||
color: var(--c-danger);
|
||||
}
|
||||
|
||||
/* E5 golem15-seo-robotstester */
|
||||
golem15-seo-robotstester .seo-robotstester__row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__field--url {
|
||||
flex: 1 1 240px;
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__field--agent {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__label {
|
||||
color: var(--c-muted);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__input,
|
||||
golem15-seo-robotstester .seo-robotstester__select {
|
||||
box-sizing: border-box;
|
||||
height: 44px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid var(--c-border-strong);
|
||||
border-radius: 10px;
|
||||
background: var(--c-surface);
|
||||
color: var(--c-text);
|
||||
font: inherit;
|
||||
font-size: 14px;
|
||||
transition: border-color 150ms, box-shadow 150ms;
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__input:focus,
|
||||
golem15-seo-robotstester .seo-robotstester__select:focus {
|
||||
outline: none;
|
||||
border-color: var(--c-primary);
|
||||
box-shadow: 0 0 0 3px var(--c-ring);
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__button {
|
||||
height: 42px;
|
||||
padding: 0 16px;
|
||||
border: 1px solid var(--c-border-strong);
|
||||
border-radius: 10px;
|
||||
background: var(--c-surface);
|
||||
color: var(--c-text);
|
||||
font: inherit;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__button:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px var(--c-ring);
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__button:disabled {
|
||||
cursor: default;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__result {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 6px;
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__result .seo-icon {
|
||||
flex: none;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__result--allowed {
|
||||
color: var(--c-ok-text, var(--c-text));
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__result--blocked {
|
||||
color: var(--c-text);
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__result--error {
|
||||
color: var(--c-danger);
|
||||
}
|
||||
|
||||
golem15-seo-robotstester .seo-robotstester__note {
|
||||
margin: 6px 0 0;
|
||||
color: var(--c-muted);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
golem15-seo-robots .seo-robots__panel {
|
||||
grid-template-columns: 1fr;
|
||||
@@ -451,6 +634,9 @@ golem15-seo-image.seo-image--invalid .seo-image__img {
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
golem15-seo-robotstxt .seo-robotstxt__control,
|
||||
golem15-seo-robotstester .seo-robotstester__input,
|
||||
golem15-seo-robotstester .seo-robotstester__select,
|
||||
golem15-seo-text .seo-text__control,
|
||||
golem15-seo-robots .seo-robots__segment,
|
||||
golem15-seo-serp .seo-serp__segment {
|
||||
|
||||
Reference in New Issue
Block a user